Activity和Service它们的Context有什么区别?

前言

电话面试时被人问到了Service能否启动Activity,由于做到相关功能所以轻松答了出来。但是面试官早有预料,他的下一个问题就是Service和Activity都是继承Context的,那么它们的Context有什么区别吗?于是,诞生了这篇文章。

从源码中找答案

看下Activity和Service继承是哪个Context:

Activity和Service它们的Context有什么区别?_第1张图片
图片.png
图片.png

Activity继承的ContextThemeWrapper又是什么东西来的,点击进去一看:

Activity和Service它们的Context有什么区别?_第2张图片
图片.png

原来它也是继承ContextWrapper,然后从注释来上看该类内部包含了主题Theme相关的东西。说到主题,还记得AndroidManifest.xml里面给Activity设置android:theme属性吗?这个应该就是他们的Context不同之处了,Service运行在后台,它没有界面就不需要主题属性,但是Activity运行在前台的界面,它需要一个界面的主题属性。

Context继承关系

本来到上面就已经足够应对面试官这个问题了,但是这引起我的好奇心,Context到底有哪些子类是我们平时经常用到的?这里我通过AS查询子类的方法将Context继承关系画了出来。


Activity和Service它们的Context有什么区别?_第3张图片
图片.png

Context主要就两个子类,ContextImpl它真正实现了Context里面全部方法,ContextWrapper构造函数中有一个Context的对象,同时ContextWrapper中提供了attachBaseContext(),这个方法用于传入一个真正的Context对象(ContextImpl的实现对象)。

Context使用场景

我们知道四大组件中都有Context,那么它们中的Context分别的使用场景是什么呢?为了避免一个坑掉两次,我决定再深入了解一下。先来看一张网上流传很久的图:

Activity和Service它们的Context有什么区别?_第4张图片
图片.png

这里说明一下吧:
1:启动Activity在这些类中是可以的,但是需要创建一个新的task或者是Context是从Activity中获取的。什么叫做在Activity中获取Context呢?就拿BroadcastReceiver说明一下好了。
BroadcastReceiver有动态注册和静态注册两种方式,如果你是在Activity动态注册广播,那么在广播的 onReceive(Context context, Intent intent)获取到Cotnext对象就是来自Activity,那么不仅可以很方便启动Activity,也可以启动Dialog(上面的图在这方面其实不够严谨的)。
如果你的BroadcastReceiver是在清单文件中静态注册的,那么获取到Cotnext对象就是 ReceiverRestrictedContext,它启动Activity就是需要 setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)来设置一个任务栈了。同时ReceiverRestrictedContext也只能启动SystemAlert类型的Dialog,而我们常用的Dialog都得依附一个Activity的Context上面。
2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用;
3:在Receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播( sticky broadcast)的当前值。(感觉日常开发基本用不到);

总结

通过这次的学习,我对Context有了更深入的了解。我们日常开发要经常用到Context,但是Context也有各种各样的限值,只有明白了这些,我们才可以躲开一些不必要的坑。

你可能感兴趣的:(Activity和Service它们的Context有什么区别?)