一个Context意味着一个场景,一个场景就是用户和操作系统交互的过程。
一、Context相关继承关系
1.ContextImpl是真正的实现类,调用context所有的方法实现都是来自于此。
2.所有的Context的实现内部都指向同一个PackageInfo对象。
3.Context本身是抽象类,ContextWrapper包装作用,内部必须有一个真正Context引用。两种方式指定Context:attachBaseContext()和构造函数。
4.ContextThemeWrapper包含与theme相关接口即android:theme指定的theme.
5.只有Activity需要theme,Service不需要实现。
二、Context的创建
创建Context实在ActivityThread中完成,具体就是创建ContextImpl对象。一共存在7处创建时机:
在PackageInfo.makeApplication()
在performLaunchActivity()
在handleCreateBackupAgent()
在handleCreateService()
在handleBindApplication()两次
在attach()中
attach()方法实在system_server进程启动时调用,应用程序启动不会调用该方法。与应用程序启动一样system_server入口都是ActivityThread.java。
1.创建Application对应的Context
每个应用程序第一次启动都会创建Application对象。会调用到handleBindApplication()方法
如上图,总结:
1.首先AMS进程调用bindApplication()函数,在该函数中新建AppBindData赋值传入参数。
2.Handler发消息执行handleBindApplication()函数。
3.在该函数中首先需要初始化一个data.info变量,存储LoadedApk对象。该对象是apk加载是的中间状态。
4.接着新建ContextImpl对象初始化包名资源管理器等。
5.新建并初始化Instrumentation对象,该对象是Activity、Application组建声明周期回调方法的代理类。ActivityThread中的组件生命周期回调都是通过该函数。
6.新建初始化Application对象,该过程发生在LoadedApk类中,总共有如下步骤:
(1)首先生成一个ContextImpl对象并初始化
(2)使用ClassLoader生成Application实例并且attach到(1)中的context
(3)ContextImpl对象拷贝一份生成的Application实例,并且将该实例添加到ActivityThread中的mAllApplications。
7.初始化ContentProvider对象
8.使用Instrumentation实例回调Application对象的onCreate()方法
2.创建Activity中的Context
启动Activity时,AMS通过IPC会调用到ActivityThread中的scheduleLaunchActivity()。
简单总结如下:
1.启动Activity时AmS通过IPC调用到ActivityThread.scheduleLaunchActivity()。在该函数中会首先新建一个ActivityClientRecord对象记录传递过来的参数。
2.接着通过Handler调用到函数handleLaunchActivity()传入刚刚保存的对象。在该函数中主要是分两步处理:
(1)performLaunchActivity()新建Activity对象并且回调部分初始生命周期函数onCreate()—>onStart()
(2)handleResumeActivity()处理onReStart()—>onResume()生命周期函数。
3.首先处理performLaunchActivity()函数
第一步执行Instrumentation.newActivity(),在该函数中使用ClassLoader新建Activity对象
第二步执行createBaseContextForActivity(),为该Activity生成一个ContextImpl对象,并且初始化互相引用,生成Window对象。
第三步使用Instrumentation对象回调Activity的生命周期函数onCreate()/onStart()/onRestoreInstanceState()/onPostCreate(),并且返回这个Activity对象
4.如果上步返回的Activity对象不为空,执行到handleResumeActivity()函数
第一步执行performResumeActivity(),在该函数中以此会回调Activity的生命周期函数:onNewIntent()/onActivityResult()/onResume(),接着会获得DecorView并add到ViewManager中。
第二步如果参数中存在startNotResume会紧接着回调onPause()函数。
以上就是Activity启动创建Context的过程。
3.创建Service中的Context
三、Context之间的关系
Context个数 = Activity个数+Service个数+1
如上应用程序包含多个ContextImpl对象但是每个对象都是对应于一个PachageInfo。
ContextImpl的大多数进行包操作的函数都是转向了mPackageInfo对象的相应方法。