参考文献:Android Context完全解析,你所不知道的Context的各种细节

1. Context 类型

context 继承结构:

20151022212109519.png

Context 的继承结构还是稍微有点复杂的,可以看到,直系子类有两个,一个是 ContextWrapper,一个是 ContextImpl。那么从名字上就可以看出,ContextWrapper 是上下文功能的封装类,而 ContextImpl 则是上下文功能的实现类。而 ContextWrapper 又有三个直接的子类, ContextThemeWrapper、Service 和 Application。其中,ContextThemeWrapper 是一个带主题的封装类,而它有一个直接子类就是 Activity。

Context 一共有三种类型,分别是Application、Activity和Service。这三个类虽然分别各种承担着不同的作用,但它们都属于 Context 的一种,而它们具体 Context 的功能则是由 ContextImpl 类去实现的。

2. Context 数量

Context数量 = Activity数量 + Service数量 + 1

3. Application Context

获取 Application 的两种方法:getApplication() 和 getApplicationContext()

区别:getApplication() 这个方法只有在 Activity 和 Service 中才能调用的到。那么也许在绝大多数情况下我们都是在 Activity 或者 Service 中使用 Application 的,但是如果在一些其它的场景,比如 BroadcastReceiver 中也想获得 Application 的实例,这时就可以借助 getApplicationContext() 方法了。

4. 使用 Application 问题

在构造方法中调用 Context 的方法就导致程序崩溃,在 onCreate() 方法中调用 Context 的方法就一切正常。Application中方法的执行顺序如下图所示:
20151108174114045.png

Application 中在 onCreate() 方法里去初始化各种全局的变量数据是一种比较推荐的做法,但是如果你想把初始化的时间点提前到极致,也可以去重写 attachBaseContext() 方法,如下所示:

public class MyApplication extends Application {
	
	@Override
	protected void attachBaseContext(Context base) {
		// 在这里调用Context的方法会崩溃
		super.attachBaseContext(base);
		// 在这里可以正常调用Context的方法
	}
	
}