知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
談?wù)?Android 的 Context
發(fā)表時(shí)間:2020-10-17
發(fā)布人:葵宇科技
瀏覽次數(shù):76
一、背景
忙活了一年,最近工作終于有點(diǎn)時(shí)間閑下來(lái)學(xué)習(xí)一下。今天復(fù)習(xí)了一下context的知識(shí)??吹芏嘀R(shí)點(diǎn)都已經(jīng)忘記了,或者是以前也沒(méi)有理解透徹。這里復(fù)習(xí)一下。順便總結(jié) Context 的知識(shí)點(diǎn)。
前面學(xué)習(xí)了Activity的啟動(dòng) ,在創(chuàng)建 從客戶端進(jìn)程的過(guò)程中 ,AMS會(huì)通知 ActivityThread 創(chuàng)建 Application ,并且調(diào)用 Application 的onCreate 方法。
這是一個(gè)應(yīng)用進(jìn)程中第一個(gè)我們常用的 Application 創(chuàng)建的地方,另外我們?cè)陧?xiàng)目中常見的 Context 還有 Activity、Service。
這些Context 有什么區(qū)別呢,下面我們來(lái)探討一下。
二、Context 的類型的繼承結(jié)構(gòu)
Android 中有好幾個(gè)Context ,其繼承結(jié)構(gòu)如下:
我們常見的Application 、Service 和 Activity 實(shí)際上都是集成至 ContextWrapper
ContextImpl 和 ContextWrapper 都繼承至Context,其中
ContextImpl :Context 的具體實(shí)現(xiàn)
ContextWrapper : 內(nèi)部持有ContextImpl 對(duì)象,采用裝飾者的模式對(duì)ContextImpl 進(jìn)行裝飾。
三、分析各個(gè)Context
3.1、Context 分析
public abstract class Context
上面可以看到 Context 類是一個(gè)抽象類,里邊實(shí)現(xiàn)了各種抽象方法, 等待著集成類去實(shí)現(xiàn)。 在Android 系統(tǒng)中,整個(gè)Context的實(shí)現(xiàn)類的結(jié)構(gòu)采用的就是
裝飾者模式,在 ContextImpl 集成并實(shí)現(xiàn)了Context的具體功能,在ContextWrapper中持有 ComtextImpl,并集成了Context 。
Application、Activity、Service 都是繼承至 ActextWrapper 。采用裝飾者模式添加不同功能。
3.2、ContextImpl 創(chuàng)建
(1)ContextImpl 的集成結(jié)構(gòu)
class ContextImpl extends Context
(2)應(yīng)用進(jìn)程 創(chuàng)建之后,AMS 通知 應(yīng)用進(jìn)程創(chuàng)建 Application ,并進(jìn)入其中 onCreate 方法
private void handleBindApplication(AppBindData data) {
... ...
//這里可以清楚看到,ActivitThread 創(chuàng)建了一個(gè) ContextImpl
//其中ContextImpl 才是真正的實(shí)現(xiàn)類,Context
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
... ...
try {
//創(chuàng)建Application
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// don't bring up providers in restricted mode; they may depend on the
// app's custom Application class
if (!data.restrictedBackupMode) {
List<ProviderInfo> providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
// For process that contains content providers, we want to
// ensure that the JIT is enabled "at some point".
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
//調(diào)用Application.onCreate() 方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
// 這重新new 了一個(gè) ContextImpl
return new ContextImpl(null, mainThread,
packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
}
3.3、分析ContextWarpper
(1)
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
創(chuàng)建了 Application ,我們看看Application 的繼承結(jié)構(gòu),他是繼承至 ContextWrapper :
public class Application extends ContextWrapper implements ComponentCallbacks2
(2) ContextWrapper 的結(jié)構(gòu)
public class ContextWrapper extends Context {
Context mBase; //這里對(duì)應(yīng)的就是ContextImpl
public ContextWrapper(Context base) {
mBase = base;
}
//是所有的ContextWrapper 對(duì)象初始化的時(shí)候,都可以調(diào)用該方法和 ContextImpl 進(jìn)行綁定
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
//獲取 ContextImpl
public Context getBaseContext() {
return mBase;
}
/// -------------- 下方列舉了幾個(gè)方法,都是直接調(diào)用了 mBase中的具體實(shí)現(xiàn)
@Override
public AssetManager getAssets() {
return mBase.getAssets();
}
@Override
public Resources getResources()
{
return mBase.getResources();
}
@Override
public PackageManager getPackageManager() {
return mBase.getPackageManager();
}
@Override
public ContentResolver getContentResolver() {
return mBase.getContentResolver();
}
... ...
}
上面可以看到,Context Wrapper 中有一個(gè)mBase 的Context 對(duì)象,其實(shí)該對(duì)象就是 ContextImpl 。所有ContextWrapper的創(chuàng)建都要在構(gòu)造函數(shù) 或者 調(diào)用 attachbaseContext 傳入 ContextImpl .可以看看前面創(chuàng)建 Application的時(shí)候是如何。
(3)Application 創(chuàng)建
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
/**
這里使用calss.newInstance 的方式創(chuàng)建一個(gè)新的 Application
創(chuàng)建之后調(diào)用 app.attachattach(context); 方法,把Application 和 ContextImpl 進(jìn)行綁定
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attachattach(context);
return app;
}
**/
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
... ...
return app;
}
上面可以看到,使用clasloader 創(chuàng)建了Application 之后,會(huì)調(diào)用 attachattach 方法把 Application 和 ContextImpl 綁定在一塊。
3.4、Application
public class Application extends ContextWrapper implements ComponentCallbacks2
Application 集成了ContextWrapper
3.5、Service
public abstract class Service extends ContextWrapper implements ComponentCallbacks2
Service 集成了ContextWrapper
3.6、ContextThemeWrapper
public class ContextThemeWrapper extends ContextWrapper
ContextThemeWrapper 集成了ContextWrapper
3.7、Activity
public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2,Window.Callback, KeyEvent.Callback,OnCreateContextMenuListener, ComponentCallbacks2,Window.OnWindowDismissedCallback
Activity 集成了 ContextThemeWrapper
3.8 、
上面的分析可以看到,
ContextImpl 才是context的具體實(shí)現(xiàn)
我們項(xiàng)目進(jìn)程接觸到的 Context 都是集成了 ContextWrapper
而ContextWrapper 是中綁定了 ContextImpl ,并且ContextWrapper是ContextImpl 的裝飾者,其中所有的具體實(shí)現(xiàn)都是調(diào)用了 ContextImpl
參考:
https://blog.csdn.net/guolin_blog/article/details/47028975
https://www.cnblogs.com/lianghe01/p/6442239.html
https://www.jianshu.com/p/dabaebe9574d
分析源碼
相關(guān)案例查看更多
相關(guān)閱讀
- 云南網(wǎng)站建設(shè)靠譜公司
- 網(wǎng)站建設(shè)需要多少錢
- 云南軟件定制公司
- 網(wǎng)站建設(shè)專家
- 云南小程序開發(fā)公司哪家好
- 搜索引擎排名
- 安家微信小程序
- 云南做網(wǎng)站
- 云南網(wǎng)站建設(shè)外包
- 網(wǎng)絡(luò)公司
- 云南網(wǎng)站建設(shè)專家
- 模版信息
- 買小程序被騙
- 云南網(wǎng)站建設(shè)方法
- 云南網(wǎng)站制作
- 云南網(wǎng)站建設(shè)首選
- 云南微信小程序開發(fā)
- 云南網(wǎng)站建設(shè)百度官方
- 云南網(wǎng)站建設(shè)快速優(yōu)化
- 網(wǎng)頁(yè)制作
- 報(bào)廢車回收
- 網(wǎng)站建設(shè)公司網(wǎng)站
- 云南網(wǎng)絡(luò)營(yíng)銷
- 北京小程序開發(fā)
- 網(wǎng)站建設(shè)方案 doc
- 昆明網(wǎng)絡(luò)公司
- 云南企業(yè)網(wǎng)站
- 網(wǎng)站建設(shè)首選
- 昆明小程序定制開發(fā)
- 小程序密鑰