Read The Fucking Source Code
引言
- Context:最熟悉的陌生人。
-
全能小伙儿
:启动Activity、启动服务、注册/发送广播、获取ContentResolver、获取类加载器、获取资源、操作数据库。
源码版本(Android R — API 30)
整体概览

1. 继承关系图

整体说明
【上下文能力】:对外交互能力(上面提到的全能小伙儿
)。
- Context:上下文能力统筹定义。
- ContextWrapper:核心组件基类,关联了ContextImpl,上下文能力执行中转端,最终交给ContextImpl执行。
- ContextImpl:上下文能力执行代理端(真正执行端)。
- ContextThemeWrapper:提供了主题能力,专门为Activity而生的。
- DecorContext:为DecorView而生,拥有主题能力,为了更好的分类与解耦(相对Activity)。
- ReceiverRestrictedWrapper:为BroadcastReceiver而生,阉割掉了绑定服务等能力。
2. 应用组件 关联 Context
2.1 Application

2.2 Activity

2.3 Service

2.4 BroadcastReceiver

2.5 ContentProvider

3. 核心方法说明
3.1 基础类 核心方法说明

3.2 应用组件 核心方法说明

4. 小结
4.1 独特的 Activity 启动
Activity 的 Context 可以直接 startActivity
,其他的Context需要加上 FLAG_ACTIVITY_NEW_TASK
flags才能使用。为什么?由于 Activity 管理 UI视图 的特殊性,Activity 接管了本该由 ContextImpl 代理类来实现的功能。所以同样的方法,在 Activity 端的处理和 ContextImpl 的处理是不一致的。
4.2 独特的 Activity 套娃
Activity 的 getBaseContext
居然是 ContextThemeWrapper,如果我们在 Activity中依然想使用 ContextImpl 的方法,举例:那么直接 getBaseContext().startActivity
,调用层次是:
- 获取 Context 引用:
getBaseContext
-> ContextThemeWrapper; - 继承关系,直接调用父类:
ContextThemeWrapper.startActivity
->ContextWrapper.startActivity
; - 调用 ContextImpl(mBase) 代理:
ContextWrapper.startActivity
->mbase.startActivity
。
对比Application的 getBaseContext().startActivity
,调用层次是:
- 获取 Context 引用:
getBaseContext
-> ContextImpl; - 调用 ContextImpl的
startActivity
。
4.3 被阉割的 BroadcastReceiver
Receiver 的 Context 不可以执行 bindService
操作。否则直接抛异常(源码就不放了)。
Receiver 的 Context 执行 registerReceiver
操作分情况处理。只有当 receiver == null
用于获取sticky广播, 允许使用。
4.4 getApplicationContext 差异
- Application:
getApplicationContext()
就是自己 Application; - Activity/Service:
getApplication()
和getApplicationContext()
都是 Application; - BroadcastReceiver:在 onReceive 的过程,使用
getBaseContext().getApplicationContext()
获取 Application; - ContentProvider:使用
getBaseContext().getApplicationContext()
获取 Application(当然有可能为空:Provider 在初始化不会创建 Application 对象,多个 Apk 运行在同一个进程的情况下,第二个 Apk 通过 Provider 初始化,则 Context 为空)。
网友评论