Context真正的实现与Context设计模式

栏目: 后端 · 发布时间: 7年前

内容简介:Context: 是一个抽象类。ContextImpl: 是Context真正的实现类。ContextWrapper: 继承Context,是一个包装类,有一个mBase的成员变量,mBase是Context类型,Context抽象方法都是由mBase实现的。子类通过调用attachBaseContext方法替换mBase成员变量。
Context真正的实现与Context设计模式

Context: 是一个抽象类。

ContextImpl: 是Context真正的实现类。

ContextWrapper: 继承Context,是一个包装类,有一个mBase的成员变量,mBase是Context类型,Context抽象方法都是由mBase实现的。子类通过调用attachBaseContext方法替换mBase成员变量。

Application, Activity, Service都是继承ContextWrapper,它们的真正的实现都是ContextImpl实例,

通过attachBaseContext方法把ContextImpl实例赋值给mBase。

所以在activity或者application中常用的方法,例如 :

  • getSharedPreferences(String name, int mode)
  • startActivity
  • sendBroadcast
  • 等等等

上述的常用的方法真正实现都是在ContextImpl

2. 源码分析

2.1 Application创建为例

Application的实例从ActivityThread的handleBindApplication(),再到LoadedApk的makeApplication()创建的。

第一步:LoadedApk的makeApplication方法

Context真正的实现与Context设计模式

cl是ClassLoader, appClass是Application的全类名, 通过ContextImpl.createAppContext创建一个ContextImpl实例,把ContextImpl实例、cl、appClass传到mInstrumentation.newApplication方法创建Application实例。

第二步: Instrumentation的newApplication方法

public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return newApplication(cl.loadClass(className), context);
    }

static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

//Application的attach方法:
/* package */ final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
复制代码

先通过classLoader的loadClass(className)获取application的class,再通过clazz.newInstance()创建Application实例,接着调用app.attach(context)方法完成初始化。 Application的attach方法里是通过attachBaseContext(context), 把第一步创建的ContextImpl实例赋值给ContextWrapper的mBase成员变量。 到此Application实例创建就完成啦。

2.2 Activity创建为例

Activity创建和Application的创建类似,在ActivityThread的performLaunchActivity方法里

第一步:ActivityThread的performLaunchActivity方法

Context真正的实现与Context设计模式
Context真正的实现与Context设计模式

通过creatBaseContextForActivity方法创建ContextImpl实例,接着通过mInstrumentation.newActivity创建Activity实例,Activity实例通过classloader,加载className,调用clazz的newInstance方法创建。再接着调用activity.attach方法完成初始化。

第二步:Activity的attach方法

Context真正的实现与Context设计模式

Activity的attach方法里是通过attachBaseContext(context), 把第一步创建的ContextImpl实例赋值给ContextWrapper的mBase成员变量。 到此Activity实例创建就完成啦。

2.3 Service创建为例

Service里的Context创建和Activity差不多

第一步:定位到ActivityThread的handleCreateService方法

java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
service.onCreate();
复制代码

调用ContextImpl的createAppContext()创建ContextImpl,调用setOuterContext()把service存储在ContextImpl的mOuterContext成员变量中,调用service.attach(),再调用service.onCreate()

第二步: Service的attach方法

public final void attach(
        Context context,
        ActivityThread thread, String className, IBinder token,
        Application application, Object activityManager) {
    attachBaseContext(context);
    mThread = thread;
    mClassName = className;
    mToken = token;
    mApplication = application;
    mActivityManager = (IActivityManager)activityManager;
    mStartCompatibility = getApplicationInfo().targetSdkVersion
            < Build.VERSION_CODES.ECLAIR;
}
复制代码

通过attachBaseContext(context), 把第一步创建的ContextImpl实例赋值给ContextWrapper的mBase成员变量。


以上所述就是小编给大家介绍的《Context真正的实现与Context设计模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员面试宝典(第5版)

程序员面试宝典(第5版)

欧立奇、刘洋、段韬 / 电子工业出版社 / 2015-10 / 55.00

容提要 《程序员面试宝典(第5版)》是《程序员面试宝典》的第5 版,在保留第4 版的数据结构、面向对象、程序设计等主干的基础上,修正了前4 版近40 处错误,解释清楚一些读者提出的问题,并使用各大IT 公司及相关企业最新面试题(2014-2015)替换和补充原内容,以反映自第4 版以来两年多的时间内所发生的变化。 《程序员面试宝典(第5版)》取材于各大公司面试真题(笔试、口试、电话面试......一起来看看 《程序员面试宝典(第5版)》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器