理解Context

栏目: IOS · Android · 发布时间: 6年前

内容简介:从应用场景的角度来说,他是一个场景,一个用户与系统交互的过程.比如当你看短信时,场景包括短信的页面,以及隐藏在后面的数据提到页面,我们应该能够联想到 Activity没错,Activity,Service都是一个Context

从应用场景的角度来说,他是一个场景,一个用户与系统交互的过程.比如当你看短信时,场景包括短信的页面,以及隐藏在后面的数据

提到页面,我们应该能够联想到 Activity

没错,Activity,Service都是一个Context

JAVA 语言角度来说,Context是一个抽象类,抽象类中包含了Application环境的一些函数,设计角度而言,Context仅提供某些功能, extends 才是类的本质,即 Activity 的本质是一个 Context ,其所实现的其他接口只是为了扩充 Context 的功能而已,扩充后的类称之为 Activity 或 Service

有多少Context

  • Application一个Context
  • 多少个Activity就有多少个Context
  • 多少个Service就有多少个Context

Context个数=1 + Activity个数 + Service个数

Application的Context创建

在博客 ActivityThread.main过程 中分析中可以知道, handleBindApplication 函数中会调用 makeApplication

makeApplication会创建Application以及创建 ContextImpl

创建 ContextImpl

ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
复制代码

这里的this是 LoadedApk 对象,该对象是在 handleBinderApplication 中赋值

data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
复制代码

在该函数中,会根据 AppBindData(handleBinderApplication中的参数) 中的ApplicationInfo的mPackageName创建一个PackageInfo对象并保存为ActivityThread类的全局对象

显然,一个应用程序中所有Activity或者Application或Servie,他们的mPackageName是一样的,即为包名,因此ActivityThread只会有一个全局的PackageInfo对象

在 newApplication的函数中会调用 Application 的 attach

attach

final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
复制代码

查看 attachBaseContext

protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }
复制代码

这个mBase就是 ContextWrapper 中的 Context

Activity的Context创建

在Launcher启动流程 的分析中可以知道,handleLaunchActivity 会调用到 performLaunchActivity,该函数会调用 createBaseContextForActivity

private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
        final int displayId;
        ...
        ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
        ...
        return appContext;
    }
复制代码

createActivityContext

createActivityContext 中的 packageInfo 信息和上小节分析的流程基本一致,他也是全局的

static ContextImpl createActivityContext(ActivityThread mainThread,
            LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
            Configuration overrideConfiguration) {
        ...

        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
                activityToken, null, 0, classLoader);

        ...
        return context;
    }
复制代码

attach

创建Context完成后,调用 activity 的 attach 函数

activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
复制代码

attach 函数中做了很多的赋值操作,其中 attachBaseContext 的函数和Application的 attachBaseContext 中作用一致,把context赋值给 ContextWrapper 的 mBase

:::danger 笔记 因此,当我们翻阅Activity源码,看到mBase时,就应该去找 ContextImpl 里的方法 :::

Service的Context创建

Service的启动和Activity类似,最终同样会调用到ActivityThread里的函数,为 scheduleCreateService,接着调用 handleCreateService

在 handleCreateService 中会创建Context

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();
复制代码

Context的创建方式和Application一致,同样在创建后会调用 attach 进行一些赋值操作,同样也有之前分析的 mBase


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

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

A Philosophy of Software Design

A Philosophy of Software Design

John Ousterhout / Yaknyam Press / 2018-4-6 / GBP 14.21

This book addresses the topic of software design: how to decompose complex software systems into modules (such as classes and methods) that can be implemented relatively independently. The book first ......一起来看看 《A Philosophy of Software Design》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具