安卓context(一)

最近看了一下深入安卓内核,毫无安卓基础的我一头深入不可自拔,看的是云里雾里,第一遍看到一半左右似乎开始失去了效率。

现在开始第二遍,并对看过的重要知识点以个人的理解进行梳理(不免有错的地方,好心人请告知,我也会经常反复阅读与更新)

其实我个人理解的话,context是一个页面或者说是一个场景。

我想刚开始我们可以从UML图挖掘我们一些基础知识。

1 可以看出我们常用的activity和service都是继承或者间接继承的是ContextWrap类。

2 有所不同的是activity是通过contextThemeWrapper来的,其实也很好理解,因为activity是有页面的所以他需要一个主题。

Context类本身是一个纯abstract类,那ContextWrap是什么呢?从他的构造函数可以看出他是context的一个包装

public class ContextWrapper extends Context {
    Context mBase;

    public ContextWrapper(Context base) {
        mBase = base;
    }

OK,一下子右边半边的类图我们已经清楚了。

接下来我们看左边的ContextImpl他往下没有子类,而从这个名字来看他应该是真正实现了context的所有抽象方法。

那么我们找一下再哪里有被调用?

我们发现代码在ActivityThread中的handleBindApplication()方法中,此方法内部调用了makeApplication方法里面恰好有new contextImpl()

public Application makeApplication(boolean forceDefaultAppClass,  
        Instrumentation instrumentation) {  
        String appClass = mApplicationInfo.className;  
        java.lang.ClassLoader cl = getClassLoader();  
        ContextImpl appContext = new ContextImpl();  //创建contextImpl对象
        appContext.init(this, null, mActivityThread);  //进行初始化赋值,请注意第一个参数this是值得mPackageInfo对象
        application app = mActivityThread.mInstrumentation.newApplication(  
                cl, appClass, appContext);  
        appContext.setOuterContext(app);  
    }
    ...  
}  

可见在创建context的时候会用到contextImpl类。

那么我们接下来看一下application、service、activity的创建过程我这边分别用/隔开,其实原理都是一样的。

1 AMS创建ApplicationInfo/Servicelnfo/Activitylnfo对象

2 AMS通过IPC调用的activeThread对象的bindApplication/scheduleCreateService/scheduleLaunchActivity方法将ApplicationInfo/Servicelnfo/Activitylnfo传入。

3 bindApplication/scheduleCreateService/scheduleLaunchActivity方法会将ApplicationInfo/Servicelnfo/Activitylnfo的值赋值给AppBindData/CreateServiceData/ActivityRecord

4 调用handleBindApplication/handleCreateService/handleLaunchActivity方法中的getPackageInfoNoChecked()方法为AppBindData/CreateServiceData/ActivityRecord的Info属性赋值PackageInfo

5 调用make方法创建对应的context

以上5个步骤分别是创建activity,application,service对象,注意packageInfo是一个全局的对象。context和package是多对一的关系

1 说简单点其实就是AMS需要把INFO信息传递给ActivityThread

2 activityThread将传入的Info信息包装一下成为自己的数据结构DATA

3 然后再去获取全局的PackageInfo对象装载到自己的DATA里

4 调用makeXXX进行创建

context的个数=service+activity+application(1个)

原文地址:https://www.cnblogs.com/sunfan1988/p/4377421.html