总共可分为 Activity context、Application context、ContextImpl(BaseContext) 这些
1. Activity Context
- android.app.ActivityThread#performLaunchActivity
- android.app.Instrumentation#newActivity 创建Activity实例,直接调用Activity的无参构造
- android.app.ActivityThread#createBaseContextForActivity 为Activity创建BaseContext。
- android.app.ContextImpl#createActivityContext 创建ContextImpl实例
设置ContextImpl的OuterContext为Activity - android.app.Activity#attach->android.content.ContextWrapper#attachBaseContext 为Activity的BaseContext赋值;
因此Activity的BaseContext每次都是新的。
2. Application Context
- android.app.LoadedApk#makeApplication,首先判断Application实例是否存在,如果存在则直接返回,不存在继续下面步骤。
- 首先调用 android.app.ContextImpl#createAppContext 创建一个ContextImpl实例;
- 调用 android.app.Instrumentation#newApplication 创建一个Application实例;
- 在调用 newApplication 之前,调用 ContextImpl.createAppContext() 方法生成 ContextImpl
- 调用 android.app.Application#attach->android.content.ContextWrapper#attachBaseContext 为Application的BaseContext赋值;
- 最后调用 android.app.ContextImpl#setOuterContext 将Application实例赋值给ContextImpl的mOuterContext,这个mOuterContext的作用:
startActivity时,如果是ActivityContext的话,就不需要加 FLAG_ACTIVITY_NEW_TASK 标记之类的
创建部分SystemService(如:android.content.Context#NOTIFICATION_SERVICE)时,也会用到mOuterContext。具体参考ContextImpl的static块。 - 因为一个进程中只会有 Application的一个实例,因此Application的BaseContext也只会存在一个。
3. 总结
- Application 和 Activity 都继承自 ContextWapper,当调用 ContextWapper 内的方法时,就是调用 ContextImpl 内的方法,具体的实现都在这里。
- 在调用 getBaseContext() 方法时,这里返回的就是 ContextImpl 对象。
- 所以,每一个 Activity / Application 都能转换为 ContextImpl 对象。
- Application的BaseContext只会存在一个,而Activity和Service的BaseContext每次都是新的.
4. 其他
- 原生 Application 创建新的 Context
Context mContext = this.getBaseContext().createPackageContext(mPackageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
网友评论