一个应用中Context的数量=Service个数+Activity个数+1。
Context有哪些子类和实现?
查看源码可以知道,Context本身是个抽象类,它的子类主要有ContextWrapper、ContextThemeWrapper,区别是后者有自己的主题资源。
毕竟是抽象类,所以Context还有一个实现类ContextImpl,是final类。
所有继承关系如下:
Context能干啥?
通过阅读Context类源码和官方API文档不难知道,Context 就相当于 Application 的大管家,主要负责:
- 四大组件的交互,包括启动 Activity、Broadcast、Service,获取 ContentResolver 等
- 获取系统/应用资源,包括 AssetManager、PackageManager、Resources、System Service 以及 color、string、drawable 等
- 文件,包括获取缓存文件夹、删除文件、SharedPreference 相关等
- 数据库(SQLite)相关,包括打开数据库、删除数据库、获取数据库路径等
- 其它辅助功能,比如设置 ComponentCallbacks,即监听配置信息改变、内存不足等事件的发生
Context和ContextWrapper、ContextThemeWrapper有啥区别?
ContextWrapper和ContextThemeWrapper都是Context的代理类,都继承于Context。
ContextWrapper 所有的操作都是通过内部成员 mBase 完成的,另外,Activity、Service 的 getBaseContext 返回的就是这个 mBase。
相比 ContextWrapper,ContextThemeWrapper 有自己的另外 Resource 以及 Theme 成员,并且可以传入配置信息以初始化自己的 Resource 及 Theme。即 Resource 以及 Theme 相关的行为不再是直接调用 mBase 的方法了,也就说,ContextThemeWrapper 和它的 mBase 成员在 Resource 以及 Theme 相关的行为上是不同的。
ContextImpl干了点啥?
创建三种context
没有重写父类的setResources,调用的是mBase的setResource。
直接创建一个Theme对象,而ContextThemeWrapper是根据Resource获取Theme,然后复制内容。
从代码中可以看出,ContextImpl 和 ContextThemeWrapper 最大的区别就是没有一个 Configuration 而已,其它的行为大致是一样的。另外,ContextImpl 可以用于创建 Activity、Service 以及 Application 的 mBase 成员,这个 Base Context 时除了参数不同,它们的 Resource 也不同。需要注意的是,createActivityContext 等方法中 setResource 是 mBase 自己调用的,Activity、Service 以及 Application 本身并没有执行 setResource。
三种Context、Base Context的区别?
Activity的 Base Context 是ContextImpl的createActivityContext 创建的。
Service的Base Context创建过程和Application一样,都是调用CcontextImpl的createAppContext,所以Service和Application的Resource是一样的。
不推荐直接使用BaseContext!
一般来说,我们会使用代理,而不是直接使用某个对象,因为那样不利于个性化,而且有可能影响原对象。
比如在activity中修改base context之后,通过getResources方法获得的资源可能和activity context不是同一份资源