中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

彩票走勢(shì)圖網(wǎng)站是用什么程序做的搜索引擎優(yōu)化的目標(biāo)

彩票走勢(shì)圖網(wǎng)站是用什么程序做的,搜索引擎優(yōu)化的目標(biāo),文件管理,廣告公司屬于什么行業(yè)目錄 前言一、Context簡(jiǎn)介二、Application Context2.1 Application Context的創(chuàng)建過(guò)程2.2 Application Context的獲取過(guò)程 三、Activity的Context創(chuàng)建過(guò)程四、Service的Context創(chuàng)建過(guò)程 前言 Context也就是上下文對(duì)象,是Android較為常用的類,但是對(duì)于Co…

目錄

  • 前言
  • 一、Context簡(jiǎn)介
  • 二、Application Context
    • 2.1 Application Context的創(chuàng)建過(guò)程
    • 2.2 Application Context的獲取過(guò)程
  • 三、Activity的Context創(chuàng)建過(guò)程
  • 四、Service的Context創(chuàng)建過(guò)程


前言

Context也就是上下文對(duì)象,是Android較為常用的類,但是對(duì)于Context,大多都停留在會(huì)用的階段,本文會(huì)從源碼角度來(lái)分析Context,從而更加深入的理解它。

一、Context簡(jiǎn)介

Context意為上下文或者場(chǎng)景,是一個(gè)應(yīng)用程序環(huán)境信息的接口。
在開(kāi)發(fā)中我們經(jīng)常會(huì)使用Context,它的使用場(chǎng)景總的來(lái)說(shuō)分為兩大類,它們分別是:

  • 使用Context調(diào)用方法,比如:啟動(dòng)Activity、訪問(wèn)資源、調(diào)用系統(tǒng)級(jí)服務(wù)等。
  • 調(diào)用方法時(shí)傳入Context,比如:彈出Toast、創(chuàng)建Dialog等。
    Activity、Service和Application都是間接的繼承自Context的,因此,可以計(jì)算出一個(gè)應(yīng)用程序進(jìn)程中有多少個(gè)Context,這個(gè)數(shù)量等于Activity和Service的總個(gè)數(shù)加1,1指的是Application的數(shù)量。

Context是一個(gè)抽象類,它的內(nèi)部定義了很多方法以及靜態(tài)常量,它的具體實(shí)現(xiàn)類為ContextImpl。和Context相關(guān)聯(lián)的類,除了ContextImpl還有ContextWrapper、ContextThemeWrapper和Activity等等,下面給出Context的關(guān)系圖。
在這里插入圖片描述

從圖中我們可以看出,ContextImpl和ContextWrapper繼承自Context,ContextThemeWrapper、Service和Application繼承自ContextWrapper。ContextWrapper和ContextThemeWrapper都是Context的包裝類,它們都含有Context類型的mBase對(duì)象,mBase具體指向的是ContextImpl,這樣通過(guò)ContextWrapper和ContextThemeWrapper也可以使用Context的方法。ContextThemeWrapper中包含和主題相關(guān)的方法(比如: getTheme方法),因此,需要主題的Activity繼承ContextThemeWrapper,而不需要主題的Service則繼承ContextWrapper。


二、Application Context

2.1 Application Context的創(chuàng)建過(guò)程

我們通過(guò)調(diào)用getApplicationContext來(lái)獲取應(yīng)用程序的全局的Application Context,那么Application Context是如何創(chuàng)建的呢?
當(dāng)一個(gè)應(yīng)用程序啟動(dòng)完成后,應(yīng)用程序就會(huì)有一個(gè)全局的Application Context。那么我們就從應(yīng)用程序啟動(dòng)過(guò)程開(kāi)始著手。

ActivityThread作為應(yīng)用程序進(jìn)程的核心類,它會(huì)調(diào)用它的內(nèi)部類ApplicationThread的scheduleLaunchActivity方法來(lái)啟動(dòng)Activity,如下所示。

frameworks/base/core/java/android/app/ActivityThread.java

    private class ApplicationThread extends ApplicationThreadNative {...@Overridepublic final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {updateProcessState(procState, false);ActivityClientRecord r = new ActivityClientRecord();...sendMessage(H.LAUNCH_ACTIVITY, r);}...   }    

在ApplicationThread的scheduleLaunchActivity方法中向H類發(fā)送LAUNCH_ACTIVITY類型的消息,目的是將啟動(dòng)Activity的邏輯放在主線程中的消息隊(duì)列中,這樣啟動(dòng)Activity的邏輯會(huì)在主線程中執(zhí)行。我們接著查看H類的handleMessage方法對(duì)LAUNCH_ACTIVITY類型的消息的處理。

frameworks/base/core/java/android/app/ActivityThread.java

private class H extends Handler {public static final int LAUNCH_ACTIVITY         = 100;
...
public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));switch (msg.what) {case LAUNCH_ACTIVITY: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");final ActivityClientRecord r = (ActivityClientRecord) msg.obj;r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);//1handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//2Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;...
}

H繼承自Handler ,是ActivityThread的內(nèi)部類。在注釋1處通過(guò)getPackageInfoNoCheck方法獲得LoadedApk類型的對(duì)象,并將該對(duì)象賦值給ActivityClientRecord 的成員變量packageInfo,其中LoadedApk用來(lái)描述已加載的APK文件。在注釋2處調(diào)用handleLaunchActivity方法,如下所示。

frameworks/base/core/java/android/app/ActivityThread.java

  private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {...Activity a = performLaunchActivity(r, customIntent);...}

接著查看performLaunchActivity方法:
frameworks/base/core/java/android/app/ActivityThread.java

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...try {Application app = r.packageInfo.makeApplication(false, mInstrumentation);...} ...return activity;}

performLaunchActivity方法中有很多重要的邏輯,這里只保留了Application Context相關(guān)的邏輯,這里ActivityClientRecord 的成員變量packageInfo是LoadedApk類型的,接著來(lái)查看LoadedApk的makeApplication方法,如下所示。

frameworks/base/core/java/android/app/LoadedApk.java

public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {if (mApplication != null) {//1return mApplication;}...try {...java.lang.ClassLoader cl = getClassLoader();...ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);//2app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);//3appContext.setOuterContext(app);//4} catch (Exception e) {...}mActivityThread.mAllApplications.add(app);mApplication = app;//5...return app;
}

注釋1處如果mApplication不為null則返回mApplication,這里假設(shè)是第一次啟動(dòng)應(yīng)用程序,因此mApplication為null。
注釋2處通過(guò)ContextImpl的createAppContext方法來(lái)創(chuàng)建ContextImpl。
注釋3處的代碼用來(lái)創(chuàng)建Application,在Instrumentation的newApplication方法中傳入了ClassLoader類型的對(duì)象以及注釋2處創(chuàng)建的ContextImpl 。
注釋4處將Application賦值給ContextImpl的Context類型的成員變量mOuterContext。
注釋5處將Application賦值給LoadedApk的成員變量mApplication,在Application Context的獲取過(guò)程中我們會(huì)再次用到mApplication。
來(lái)查看注釋3處的Application是如何創(chuàng)建的,Instrumentation的newApplication方法如下所示。
frameworks/base/core/java/android/app/Instrumentation.java

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

Instrumentation中有兩個(gè)newApplication重載方法,最終會(huì)調(diào)用上面這個(gè)重載方法。注釋1處通過(guò)反射來(lái)創(chuàng)建Application,并調(diào)用了Application的attach方法,并將ContextImpl傳進(jìn)去:
frameworks/base/core/java/android/app/Application.java

/* package */ final void attach(Context context) {attachBaseContext(context);mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

attach方法中調(diào)用了attachBaseContext方法,它的實(shí)現(xiàn)在Application的父類ContextWrapper中,代碼如下所示。
frameworks/base/core/java/android/content/ContextWrapper.java

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

從上文得知,這個(gè)base指的是ContextImpl,將ContextImpl賦值給ContextWrapper的Context類型的成員變量mBase。


2.2 Application Context的獲取過(guò)程

熟知了Application Context的創(chuàng)建過(guò)程,那么它的獲取過(guò)程會(huì)非常好理解。我們通過(guò)調(diào)用getApplicationContext方法來(lái)獲得Application Context,getApplicationContext方法的實(shí)現(xiàn)在ContextWrapper中,如下所示。
frameworks/base/core/java/android/content/ContextWrapper.java

    @Overridepublic Context getApplicationContext() {return mBase.getApplicationContext();}

從上文得知,mBase指的是ContextImpl,我們來(lái)查看 ContextImpl的getApplicationContext方法:
frameworks/base/core/java/android/app/ContextImpl.java

Override
public Context getApplicationContext() {return (mPackageInfo != null) ?mPackageInfo.getApplication() : mMainThread.getApplication();
}

如果LoadedApk不為null,則調(diào)用LoadedApk的getApplication方法,否則調(diào)用AvtivityThread的getApplication方法。由于應(yīng)用程序這時(shí)已經(jīng)啟動(dòng),因此LoadedApk不會(huì)為null,則會(huì)調(diào)用LoadedApk的getApplication方法:
frameworks/base/core/java/android/app/LoadedApk.java

   Application getApplication() {return mApplication;}

這里的mApplication我們應(yīng)該很熟悉,它在上文LoadedApk的makeApplication方法的注釋5處被賦值。這樣我們通過(guò)getApplicationContext方法就獲取到了Application Context。


三、Activity的Context創(chuàng)建過(guò)程

當(dāng)我們?cè)贏ctivity中調(diào)用startActivity方法時(shí),其實(shí)調(diào)用的是Context的startActivity方法,如果想要在Activity中使用Context提供的方法,務(wù)必要先創(chuàng)建Context。Activity的Context會(huì)在Activity的啟動(dòng)過(guò)程中被創(chuàng)建, ActivityThread是應(yīng)用程序進(jìn)程的核心類,它的內(nèi)部類ApplicationThread會(huì)調(diào)用scheduleLaunchActivity方法來(lái)啟動(dòng)Activity,scheduleLaunchActivity方法如下所示。

frameworks/base/core/java/android/app/ActivityThread.java

Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {updateProcessState(procState, false);ActivityClientRecord r = new ActivityClientRecord();r.token = token;...sendMessage(H.LAUNCH_ACTIVITY, r);
}

scheduleLaunchActivity方法會(huì)將啟動(dòng)Activity的參數(shù)封裝成ActivityClientRecord ,sendMessage方法向H類發(fā)送類型為LAUNCH_ACTIVITY的消息,并將ActivityClientRecord 傳遞過(guò)去。sendMessage方法的目的是將啟動(dòng)Activity的邏輯放在主線程中的消息隊(duì)列中,這樣啟動(dòng)Activity的邏輯就會(huì)在主線程中執(zhí)行。
H類的handleMessage方法中會(huì)對(duì)LAUNCH_ACTIVITY類型的消息進(jìn)行處理,其中調(diào)用了handleLaunchActivity方法,而handleLaunchActivity方法中又調(diào)用performLaunchActivity方法,來(lái)查看performLaunchActivity方法。
frameworks/base/core/java/android/app/ActivityThread.java

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...Activity activity = null;try {java.lang.ClassLoader cl = r.packageInfo.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);//1...}} catch (Exception e) {...}try {...if (activity != null) {Context appContext = createBaseContextForActivity(r, activity);//2.../***3*/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); ...if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//4} else {mInstrumentation.callActivityOnCreate(activity, r.state);}...}return activity;}

performLaunchActivity方法中有很多重要的邏輯,這里只保留了Activity的Context相關(guān)的邏輯。在注釋1處用來(lái)創(chuàng)建Activity的實(shí)例。注釋2處通過(guò)createBaseContextForActivity方法用來(lái)創(chuàng)建Activity的ContextImpl,并將ContextImpl傳入注釋3處的activity的attach方法中。在注釋4處Instrumentation的callActivityOnCreate方法中會(huì)調(diào)用Activity的onCreate方法。
我們先來(lái)查看注釋2出的createBaseContextForActivity方法:

frameworks/base/core/java/android/app/ActivityThread.java

 private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {...ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token, displayId, r.overrideConfig);//1appContext.setOuterContext(activity);//2Context baseContext = appContext;...return baseContext;}

在注釋1處調(diào)用ContextImpl的createActivityContext方法來(lái)創(chuàng)建ContextImpl,注釋2處調(diào)用了ContextImpl的setOuterContext方法,將此前創(chuàng)建的Activity 實(shí)例賦值給ContextImpl的成員變量mOuterContext,這樣ContextImpl也可以訪問(wèn)Activity的變量和方法。
我們?cè)倩氐紸ctivityThread的performLaunchActivity方法,查看注釋3處的Activity的attach方法,如下所示。
frameworks/base/core/java/android/app/Activity.java

 final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window) {attachBaseContext(context);//1mFragments.attachHost(null /*parent*/);mWindow = new PhoneWindow(this, window);//2mWindow.setWindowControllerCallback(this);mWindow.setCallback(this);//3mWindow.setOnWindowDismissedCallback(this);...mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);//4if (mParent != null) {mWindow.setContainer(mParent.getWindow());}mWindowManager = mWindow.getWindowManager();//5mCurrentConfig = config;}

在注釋2處創(chuàng)建PhoneWindow,它代表應(yīng)用程序窗口。PhoneWindow在運(yùn)行中會(huì)間接觸發(fā)很多事件,比如點(diǎn)擊事件、菜單彈出、屏幕焦點(diǎn)變化等事件,這些事件需要轉(zhuǎn)發(fā)給與PhoneWindow關(guān)聯(lián)的Actvity,轉(zhuǎn)發(fā)操作通過(guò)Window.Callback接口實(shí)現(xiàn),Actvity實(shí)現(xiàn)了這個(gè)接口,在注釋3處將當(dāng)前Activity通過(guò)Window的setCallback方法傳遞給PhoneWindow。
注釋4處給PhoneWindow設(shè)置WindowManager,并在注釋5處獲取WindowManager并賦值給Activity的成員變量mWindowManager ,這樣在Activity中就可以通過(guò)getWindowManager方法來(lái)獲取WindowManager。
在注釋1處調(diào)用了ContextThemeWrapper的attachBaseContext方法,如下所示。

frameworks/base/core/java/android/view/ContextThemeWrapper.java

Override
protected void attachBaseContext(Context newBase) {super.attachBaseContext(newBase);
}

attachBaseContext方法接著調(diào)用ContextThemeWrapper的父類ContextWrapper的attachBaseContext方法:

frameworks/base/core/java/android/content/ContextWrapper.java

protected void attachBaseContext(Context base) {if (mBase != null) {throw new IllegalStateException("Base context already set");}mBase = base;//1
}

注釋1處的base指的是一路傳遞過(guò)來(lái)的Activity的ContextImpl,將它賦值給ContextWrapper的成員變量mBase。這樣ContextWrapper的功能就可以交由ContextImpl處理,舉個(gè)例子:
frameworks/base/core/java/android/content/ContextWrapper.java

@Override
public Resources.Theme getTheme() {return mBase.getTheme();
}

當(dāng)調(diào)用ContextWrapper的getTheme方法,其實(shí)就是調(diào)用的ContextImpl的getTheme方法。
Activity的Context創(chuàng)建過(guò)程就講到這里。 總結(jié)一下,在啟動(dòng)Activity的過(guò)程中創(chuàng)建ContextImpl,并賦值給ContextWrapper的成員變量mBase中。Activity繼承自ContextWrapper的子類ContextThemeWrapper,這樣在Activity中就可以使用ContextImpl了。


四、Service的Context創(chuàng)建過(guò)程

Service的Context創(chuàng)建過(guò)程與Activity的Context創(chuàng)建過(guò)程類似,也是在Service的啟動(dòng)過(guò)程中被創(chuàng)建 ActivityThread的內(nèi)部類ApplicationThread會(huì)調(diào)用scheduleCreateService方法來(lái)啟動(dòng)Service,如下所示。
frameworks/base/core/java/android/app/ActivityThread.java

public final void scheduleCreateService(IBinder token,ServiceInfo info, CompatibilityInfo compatInfo, int processState) {...sendMessage(H.CREATE_SERVICE, s);}

sendMessage方法向H類發(fā)送CREATE_SERVICE類型的消息,H類的handleMessage方法中會(huì)對(duì)CREATE_SERVICE類型的消息進(jìn)行處理,其中調(diào)用了handleCreateService方法:
frameworks/base/core/java/android/app/ActivityThread.java

 private void handleCreateService(CreateServiceData data) {...try {if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);ContextImpl context = ContextImpl.createAppContext(this, packageInfo);//1context.setOuterContext(service);Application app = packageInfo.makeApplication(false, mInstrumentation);service.attach(context, this, data.info.name, data.token, app,ActivityManagerNative.getDefault());//2service.onCreate();...} catch (Exception e) {... }}

在注釋1處創(chuàng)建了ContextImpl ,并將該ContextImpl傳入注釋2處service的attach方法中:
frameworks/base/core/java/android/app/Service.java

 public final void attach(Context context,ActivityThread thread, String className, IBinder token,Application application, Object activityManager) {attachBaseContext(context);//1mThread = thread;           // NOTE:  unused - remove?mClassName = className;mToken = token;mApplication = application;mActivityManager = (IActivityManager)activityManager;mStartCompatibility = getApplicationInfo().targetSdkVersion< Build.VERSION_CODES.ECLAIR;}

注釋1處調(diào)用了ContextWrapper的attachBaseContext方法。
frameworks/base/core/java/android/content/ContextWrapper.java

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

attachBaseContext方法在前文已經(jīng)講過(guò),這里不再贅述。
Service的Context創(chuàng)建過(guò)程就講解到這里,它和Activity的Context創(chuàng)建過(guò)程類似。


參考鏈接:
深度詳解 Android 之 Context
Android Context完全解析,你所不知道的Context的各種細(xì)節(jié)

http://www.risenshineclean.com/news/28146.html

相關(guān)文章:

  • 海外 網(wǎng)站 推廣百度一下百度知道
  • 網(wǎng)站是否被百度收錄網(wǎng)址信息查詢
  • 怎嗎做網(wǎng)站掙錢揭陽(yáng)seo快速排名
  • 如何用騰訊云做網(wǎng)站seo百度關(guān)鍵詞優(yōu)化
  • 聊城做網(wǎng)站好的公司淘寶網(wǎng)店代運(yùn)營(yíng)正規(guī)公司
  • 做網(wǎng)站美工廣州seo推廣公司
  • 山西傳染病最新消息今天唐山seo排名外包
  • 如何建設(shè)網(wǎng)站方便后期維護(hù)東莞網(wǎng)絡(luò)推廣公司
  • 做培訓(xùn)的網(wǎng)站建設(shè)網(wǎng)絡(luò)推廣工作內(nèi)容怎么寫
  • 游戲軟件開(kāi)發(fā)屬于什么專業(yè)seo內(nèi)部?jī)?yōu)化具體做什么
  • 宣城市網(wǎng)站集約化建設(shè)茶葉網(wǎng)絡(luò)推廣方案
  • 長(zhǎng)沙做企業(yè)網(wǎng)站的公司中國(guó)網(wǎng)站排名
  • 網(wǎng)站制作難點(diǎn)故事式的軟文廣告例子
  • 青島網(wǎng)站建設(shè)青島新思維百度用戶服務(wù)中心人工電話
  • 浙江省建設(shè)通網(wǎng)站迅雷磁力
  • 網(wǎng)站建設(shè)找星火龍關(guān)鍵詞排名代做
  • PC端網(wǎng)站開(kāi)發(fā)以及設(shè)計(jì)費(fèi)用qq群推廣網(wǎng)站
  • 網(wǎng)站建設(shè)公司排行榜搜索引擎優(yōu)化內(nèi)容包括哪些方面
  • 貞豐縣住房和城鄉(xiāng)建設(shè)局網(wǎng)站鄭州關(guān)鍵詞排名顧問(wèn)
  • 成都設(shè)計(jì)公司官網(wǎng)東莞seo網(wǎng)絡(luò)營(yíng)銷
  • 泉州建設(shè)工程質(zhì)量網(wǎng)站千鋒教育學(xué)費(fèi)一覽表
  • 創(chuàng)建了網(wǎng)站百度推廣開(kāi)戶費(fèi)用
  • 小白學(xué)做網(wǎng)站買什么書優(yōu)化網(wǎng)站排名工具
  • wordpress查看網(wǎng)站內(nèi)容站長(zhǎng)工具服務(wù)器查詢
  • wordpress 操作數(shù)據(jù)庫(kù)大連seo顧問(wèn)
  • 唐山企業(yè)網(wǎng)站建設(shè)濟(jì)南百度
  • 云主機(jī) 做網(wǎng)站鏈接交換公司
  • 上海網(wǎng)站搜索排名婚戀網(wǎng)站排名前三
  • 做外貿(mào)網(wǎng)站好的公司志鴻優(yōu)化設(shè)計(jì)答案網(wǎng)
  • 網(wǎng)站產(chǎn)品詳情用哪個(gè)軟件做的sem競(jìng)價(jià)培訓(xùn)班