关于android:Android入门教程-认识-Android-Context

52次阅读

共计 3798 个字符,预计需要花费 10 分钟才能阅读完成。

APP 开发中,咱们须要应用 app 的资源,比方文字、图片,Activity、Service 或者 broadcastReceiver 等等。时常也会用到 getApplicationContext() 来获取一个 Context 对象。那么这个 Context 到底是什么呢?

Context 类简介

context 含意有语境,上下文,背景,环境等等。Context 是维持 Android 程序中各组件可能失常工作的一个外围性能类。

Context 是一个抽象类。它是一个 app 全局环境的“接口”,由 Android 零碎提供继承类(例如 Activity、Service、Application 等)。它能连贯到利用的资源,也能应用利用级的操作,比方启动 activity,播送和接管 intent。

应用程序中 Context 的总数目为: 总 Context 个数 = Activity 个数 + Service 个数 + 1(Application Context)

Context 的子类

简略的继承关系示意

Context
├── ContextImpl
└── ContextWrapper
    ├── Application
    ├── ContextThemeWrapper
    │   └── Activity
    └── Service

从继承关系图中能够看出,Application 类、Service 类和 Activity 类都继承了 Context 类。应用程序被启动后,会为应用程序创立一个全局的 Application 对应的 Context 对象。ContextImpl 类是 Context 的真正实现。

ContextWrapper 类是封装类。能够在不扭转 ContextImpl 的状况下,为其减少一些自定义操作。ContextWrapper 中的 mBase 实际上是一个 ContextImpl 对象。而 ContextImpl 类中的 mOuterContext 是一个 Context 对象,指向绝对应的 Activity 或 Service 或 Application。

ContextImpl

Context 是一个抽象类,子类 ContextImpl 实现了 Context 的办法;为 Activity 和其余利用组件提供根本的 context 对象。ContextImpl.java (frameworks\base\core\java\android\app)

/**
 * Common implementation of Context API, which provides the base
 * context object for Activity and other application components.
 */
class ContextImpl extends Context {/*...*/}

ContextWrapper

Wrapper 有封装的意思;ContextWrapper 是 Context 的封装类。这里应用了装璜者模式,构造方法中传入了一个 Context 实例。ContextWrapper 持有 ContextImpl 对象。能够在不扭转 ContextImpl 的状况下减少一些操作。

ContextWrapper.java (frameworks\base\core\java\android\content)
/**
 * Proxying implementation of Context that simply delegates all of its calls to
 * another Context.  Can be subclassed to modify behavior without changing
 * the original Context.
 */
public class ContextWrapper extends Context {
    Context mBase;

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

具体操作中,Application 类、Activity 和 Service 类与 ContextImpl 产生交加。

ContextThemeWrapper

容许在封装的 context 中批改主题(theme)

ContextThemeWrapper.java (frameworks\base\core\java\android\view)
/**
 * A ContextWrapper that allows you to modify the theme from what is in the
 * wrapped context.
 */
public class ContextThemeWrapper extends ContextWrapper {/* ... */}

其中提供了对于 theme 的办法,app 开发中 android:theme 与此有关。雷同的代码,雷同的调用,应用不同的 theme 会有不同的成果。

getApplicationContext() 和 getBaseContext()

public class ContextWrapper extends Context {
    Context mBase;
    ......
    @Override
    public Context getApplicationContext() {return mBase.getApplicationContext();
    }
    ......
    /**
     * @return the base context as set by the constructor or setBaseContext
     */
    public Context getBaseContext() {return mBase;// Don't use getBaseContext(), just use the Context you have.
    }
    ......
}
getApplicationContext() = android.app.Application@39d42b0e
getBaseContext() = android.app.ContextImpl@1f48c92f

getApplicationContext() 从 application 获得 context。getBaseContext() 从实现类 ContextImpl 那得来。

Context 子类创立流程

Application 的创立流程

咱们把关注点先放在 application 上,临时疏忽源码中的其余信息。

流程形容:

LoadedApk 先通过 classLoaderloadClass(className) 获取 application 的 class,再通过 clazz.newInstance() 创立 Application 实例。接着调用 app.attach(context) 办法实现初始化。

Application 的 attach 办法里调用了本人的 attachBaseContext(context), 把第一步创立的 ContextImpl 实例赋值给 ContextWrappermBase 成员变量。到此 Application 实例创立就实现了。

Activity 的创立 – performLaunchActivity

这里关注的是 Activity 的实例化以及之前的一些筹备过程。

流程简析:

次要关注 ActivityThreadperformLaunchActivity 办法。通过ContextImplcreateActivityContext 取得一个 ContextImpl 实例,称为 appContextInstrumentationnewActivity 返回了一个 Activity 实例。

LoadedApk.makeApplication 能够取得以后的 application,如果以后没有则新建一个 application。最初通过 ContextImpl.setOuterContext 和 Activity 的attach 办法,将 ContextImpl 实例与 Activity 实例关联到一起。

应用

自定义 Application

新建一个 MyApplication 类,继承自 Application

import android.app.Application;
import android.content.Context;

public class MyApplication extends Application {
    private static Context context;

    public static Context getMyContext() {return context;}

    @Override
    public void onCreate() {super.onCreate();
        context = getApplicationContext();}
}

在 Manifest 中应用 MyApplication;

    <application
        android:name="com.rust.aboutview.MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
    ......

即可在不同的中央调用 getMyContext() 办法

MyApplication.getMyContext()

【Android 零根底入门教程视频参考】

正文完
 0