首先来谈一谈Context 什么是Context以及作用
它是应用环境的全局接口,一个抽象类,它的实现是由Android系统提供,是一个系统资源类,启动Activity
,发送广播
其中Application、activity与service中有context,广播与contentProvider没有context
那application中的Context创建流程是怎么样的,下面就来谈一谈创建流程
application
的context创建:与application
一起初始化,通过Zygote调用fork出一个进程,然后执行一个入口函数activitythread
的main函数,向ams报告启动好了,让应用创建application,内部调用handleBindApplication
先创建application
对象,再执行application的onCreate回调,创建application,是由newApplication
内部调用ClassLoader
加载类,调用clazz.newInstance
,调用attach
传入上下文对象
总结以下结论:
Application<-ContextWrapper<-Context
<init>->attachBaseContext->onCreate
ContextWrapper
里包含一个Context
,调用都委托给他Context在不同组件也有区别,下面一一列出不同,这里的Activity与Service中Context的作用是相同的,就不再列出Service中Context的作用
Activity
的Context
作用:跟随activity一起启动,内部调用performLaunchActivity,newActivity,classLoad
加载,newInstance
返回Activity
对象,最后执行activity
的onCreate
对象 Activity<-ContextThemeWrapper<-ContextWrapper
<init>->attachBaseContext->onCreate
BroadcastReceive
;动态注册是注册时用的context,静态注册是以application
为mBase的ContextWrapper
ContentProvider
:初始化传入的application的context
,它onCreate在applicationonCreate
之前调用Context
的数量等于Activity
的个数 + Service
的个数 + 1,这个1为Application.
activity
对象自己getBaseContext
返回的是ContextWrapper
的mBase
getApplicationContext
是Context的抽象函数getApplication
是activity与servic
e特有的,广播不能调用获取context,只能调用
getApplicationContext
组件构造->attachBaseContext
传入上下文->onCreate
Application
数量相等,多个进程对应多个Application
ContextWrapper
,所以调用是交给mBase
,如果通过反射替换掉mBase
,那么Application
调用也会更换attachBaseContext,onCreate
new Application ->application.attachBaseContetx->application.onCreate
,不要在构造函数中使用上下文,由于还没有准备好下面有两个注意点,是我们在开发过程的尤其要注意的,否则,对我们的应用有很大的影响 首先第一点就是:
bindAppication
在UI线程中执行。AMS不受影响,是oneway
,发起调用就会返回,不会等待结果。会耽误应用要启动的组件第二点也要注意:
application
中有一个静态变量name,在mainActivity
中设置这个类,马上跳转到TestActivity
中获取这个值,但是此时切换到后台,系统会因为内存不足,在切回来,就会重建这个应用,创建Application
,恢复testActivity
,此时Application
的name
就是空值,报空指针异常,所以说避免在Application中使用静态变量属性