认识 Android Context¶
Android L
app开发中,我们需要使用app的资源,比如文字、图片,Activity、Service或者broadcastReceiver等等。时常也会用到getApplicationContext()
来获取一个Context对象。那么这个Context到底是什么呢?
我们一起来认识一下Android中的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;
}
// ...
}
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 { /* ... */ }
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
Context子类创建流程¶
Application的创建流程¶
我们把关注点先放在application上,暂时忽略源码中的其他信息。
流程描述:
LoadedApk
先通过classLoader
的loadClass(className)
获取application的class
,再通过clazz.newInstance()
创建Application
实例。接着调用app.attach(context)
方法完成初始化。 Application的attach方法里调用了自己的attachBaseContext(context)
, 把第一步创建的ContextImpl
实例赋值给ContextWrapper
的mBase
成员变量。 到此Application实例创建就完成了。
Activity的创建 - performLaunchActivity¶
这里关注的是Activity的实例化以及之前的一些准备过程。
流程简析:
主要关注ActivityThread
的performLaunchActivity
方法。通过ContextImpl
的createActivityContext
获得一个ContextImpl实例,称为appContext
。Instrumentation
的newActivity
返回了一个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();
}
}
<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">
......
参考¶
http://blog.csdn.net/yanbober/article/details/45967639
https://xujiaojie.github.io/2017/09/18/%E5%AE%8C%E5%85%A8%E5%89%96%E6%9E%90Android%E4%B8%8A%E4%B8%8B%E6%96%87%E7%8E%AF%E5%A2%83Context/
https://xujiaojie.github.io/2017/09/18/%E5%AE%8C%E5%85%A8%E5%89%96%E6%9E%90Android%E4%B8%8A%E4%B8%8B%E6%96%87%E7%8E%AF%E5%A2%83Context/
https://juejin.im/post/5c37f402e51d4552411ac0a0
本文也发布在
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~