Context源码分析

网友投稿 267 2022-10-25


Context源码分析

Context是什么?

Context的字面意思是“上下文”,那么这个“上下文”到底指的是什么?“上”指的是什么?“下”指定的是什么?个人的理解,有助于自己的理解的方式,不一定对,如果有更好的看法可以一块交流学习。个人的理解,“上”指的是在APP启动的时候,就与Context有关了,这个时候还是系统启动阶段,就与Context发生了联系。“下”指定的是在APP界面正常显示出来以后,正常与用户交互的过程中,可以用Context获取资源,系统服务等。所以Context所谓的上下文就是承上启下的作用。

Context的类的继承关系从上图可以看到,Context只有一个实现类ContextImpl,Application,Service,Activity都是直接或者间接继承了ContextWrapper,ContextWrapper中有一个变量mBase,也是个Context类型,实际是ContextImpl的对象,Application,Service,Activity所有的操作都是委托给了mBase实现。Context既然是承上启下,是个上下文,和APP启动流程有关,先来看看系统的启动流程和APP的启动流程,都在一张图里,如下:

从上图可以看到:

Context有什么作用?

1 访问当前应用的资源

getResourcesgetAssets

2 启动其它组件

ActivityService

3 获取系统服务

getSystemService

Application对象的ContextImpl对象创建过程

1 通过上面的系统启动流程和APP启动流程分析可知:第一个APP应用都是由AMS通过binder机制创建一个新的进程,然后调用ActivityThread类中的main方法开始的。很多人可能会感到奇怪为啥Android也是基于Java实现的,为啥没有看到main方法呢?其实整个App应用的入口就是ActivityThread.main方法.所有有关Application, Activity,Service的创建都是在ActivityThread类中,其实该类就是我们App的主线程。在ActivityThread中有一个方法 performLaunchActivity()方法,在这个方法里面就创建了Application,Activity。我们看一下这个方法。如下图

调用mInstrumentation.newActivity()方法创建Activity。newActivity代码如下图

可以看到,创建Activity以后,调用了Activity的attach方法,第一个参数就是context,在这里Activity就和context发生了联系,这个context其实就是ContextImpl的实例。接着上面的第一张图 performLaunchActivity继续往下走,如下图:

通过上图可以看到,在创建完了activity,并且调用了activity.attach()方法之后,开始创建Application对象,如下

Application app = r.packageInfo.makeApplication(false,mInstrumentation)

makeApplication代码如下:

随后又创建了一个ContextImpl的实例,代码如下

//创建ContextImpl实例ContextImpl appContext = new ContextImpl();//初始化ContextImpl实例appContext.init(this,null,mActivityThread);//把appContext传给了newApplication方法app = mActivityThread.mInstrumentation.newApplication(cl,appClass,appContext);//与Application发生联系,ContextImpl实例保存了Application的实例appappContext.setOuterContext(app); mActivityThread.mAllApplication.add(app); mApplication = app;

下面看下newApplicaiton()方法,代码如下:

static public Application newApplication(Class clazz,Context context){    //通过反射创建Application实例     Application app = (Application)clazz.newInstance();    //把上面传进来的ContextImpl实例通过attach方法保存了起来     app.attach(context);    //返回Application实例     return app; }

创建完Application并且通过调用application实例的attach方法与ContextImpl实例发生了联系,接下来就应该调用application的onCreate()方法了。代码如下:

public void callApplicationOnCreate(Application app){    //调用Application的onCreate方法     app.onCreate(); }

创建了activity,也创建了application并且调用了application的attach和onCreate方法,接下来应该调用activity的onCreate方法了。还是在performLanucherActivity方法中。如下图:

如上图,通过mInstructation的callActivityOnCreate()方法调用activity的onCreate()。这段代码和调用application的onCreate()方法的逻辑类似,自己可以看一下。这里不再帖出代码

*** 通过上面的分析可以知道,Context是什么时候创建的,是怎么创建的,何时初始化的,如何与Application和Activity发生联系的等 ***

Application的生命周期为什么这么长?

我们知道,Application的生命周期是和APP进程一样长的,Application对应的context也是一样,为什么Application的生命周期为什么这么长?

通过上面的分析可以知道,APP进程的入口是ActivityThread.main()方法,在这个方法中创建了一个ActivityThread的实例,通过Handler阻塞在那。ActivityThread的实例就会一直存在,如果APP不退出的话,而ActivityThread的实例中保存了application的mAllApplications,这是一个数组,保存Application实例的,在创建Application实例的时候,通过mActivityThread.mAllApplications.add(app),把app保存起来了,通过强引用可以知道,ActivityThread引用了application实例,而ActivityThread实例又在进程的循环中,一直在阻塞,所以Application的生命周期和进程一样。

Context的用法注意

下面以一张图来说明几种Context的不同点和用法。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring事件监听详解
下一篇:网卡备份文件生效
相关文章

 发表评论

评论列表