溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

發(fā)布時(shí)間:2020-07-07 12:31:14 來(lái)源:網(wǎng)絡(luò) 閱讀:925 作者:屠夫章哥 欄目:移動(dòng)開(kāi)發(fā)

Activity 中mParent 成員變量是如何被賦值的。 - CSDN博客

  • Android 視圖渲染過(guò)程的源碼分析 - CSDN博客

  • android系統(tǒng)啟動(dòng)框架、Activity界面顯示過(guò)程詳解 - snow_flower - 博客園

  • Android源碼之Activity從啟動(dòng)到顯示到界面 - 阿里云



以下的源碼都是API26.


?context的初始化過(guò)程:https://www.jianshu.com/p/7d4b605f5060

????????----------------------------------------------------------------------------------------------------------------------------------------------

? ? ? ??系統(tǒng)級(jí)別的Context實(shí)例化過(guò)程:

????????SystemServer的run方法中,調(diào)用createSystemContext方法

????????Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

????????1)systemMain方法

? ? ? ? 通過(guò)ActivityThread的systemMain方法創(chuàng)建了一個(gè)系統(tǒng)級(jí)別的ActivityThread

????????Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

????????調(diào)用activityThread的attach方法,傳入true。

????????該方法創(chuàng)建了application并調(diào)用了onCreate方法。

? ? ? ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? ? ? 2)getSystemContext()

? ? ??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? ? ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? ? ? 以上是系統(tǒng)級(jí)別的context實(shí)例化過(guò)程,為了弄清activity這個(gè)context是如何實(shí)例化的,就得研究一下activity的啟動(dòng)過(guò)程。https://blog.csdn.net/qq_23547831/article/details/51224992

? ? ??需要注意的是activity,service啟動(dòng)activity的過(guò)程都各不一樣,activity復(fù)寫(xiě)了startActivity方法,service直接調(diào)用了父類(lèi)的方法。

? ? ?activity之所以要復(fù)寫(xiě)startActivity方法,是為了復(fù)用activity獨(dú)有的startActivityForResult方法。

? ? ??最終都會(huì)調(diào)用到Instrumentation的啟動(dòng)activity方法,再調(diào)用ActivityManagerNative

? ? ??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? ? ?

????????Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

????????

?很明顯,啟動(dòng)activity使用了binder。

????這個(gè)"activity"為key的service是何時(shí)添加的呢?

? ??我嘗試著在SystemServer里找,但是沒(méi)有找到。在A(yíng)ctivityManagerService自身的代碼里找到。而setSystemProcess在SystemServer里被調(diào)用。

? ? ? ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

?????Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? ??

ActivityManagerService的實(shí)例是怎么創(chuàng)建出來(lái)的呢?

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

?

?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? ? ?

上面根據(jù)字節(jié)碼反射創(chuàng)建了service的實(shí)例,實(shí)例實(shí)際是ActivityManagerService的內(nèi)部類(lèi):Lifecycle.

??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

調(diào)用了Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


getService方法得到了真正的ActivityManagerService.

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? 調(diào)用了service的onStart方法。

??

? 上面說(shuō)了這么多,關(guān)于A(yíng)ctivityManagerService創(chuàng)建的過(guò)程。? ? ??

? 但是疑問(wèn)尚在:

? 1)activity怎么就具備了context的特性了,它也沒(méi)有new,怎么使之成為一個(gè)context。

? 2)startActivity怎么android系統(tǒng)就會(huì)彈出一個(gè)界面


?前面Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

?開(kāi)啟activity,最終會(huì)通過(guò)Binder機(jī)制(數(shù)據(jù)傳輸機(jī)制比較麻煩,后面研究)跨進(jìn)程調(diào)用

? ActivityManagerServcie的startActivityAsUser方法:

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

繼而調(diào)用ActivityStarter的startActivityMayWait方法

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

在方法中又會(huì)調(diào)用到startActivityLocked方法

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


方法最后會(huì)調(diào)用到?startActivityUnchecked方法

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


最終調(diào)用了ActivityStack的startActivityLocked方法:

?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


注意下面這部分代碼,不同版本的源碼會(huì)有很大的區(qū)別。

?

1)首先判斷開(kāi)啟的activity是否是新任務(wù),分別做不同的處理。

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程



? 2)主要是調(diào)用WindowManager

? ? ***準(zhǔn)備事務(wù)

? ? ***添加token

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


調(diào)用WindowManagerService的H來(lái)發(fā)送消息


Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


注意ensureActivitiesVisibleLocked這個(gè)方法

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

接著方法調(diào)用順序:

??makeVisibleAndRestartIfNeeded (ActivityStack)

??startSpecificActivityLocked (ActivityStackSupervisor)

??realStartActivityLocked?(ActivityStackSupervisor)

? 此方法內(nèi)部會(huì)調(diào)用?app.thread.scheduleLaunchActivity,這個(gè)app.thread是IApplicationThread類(lèi)的實(shí)例,具體的子類(lèi)是哪個(gè)呢?

? 下面的源碼為API26


? app即Proce***ecord類(lèi)

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? 在里面搜索thread的set方法:
??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? makeActive點(diǎn)擊發(fā)現(xiàn)有2處引用:

? 引用1:

? ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

??

? ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

??

??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


? 引用2:

??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? 找到上一個(gè)調(diào)用的地方

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

?

??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

?

? 由上面的分析可知:app.thread的thread是ActivityThread

? 下面看它的scheduleLaunchActivity方法,看它是如何啟動(dòng)Activity的:

? ?1)發(fā)送消息給H這個(gè)Handler

? ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? ?注意這個(gè)r變量,在后面有關(guān)Activity渲染繪制的源碼中會(huì)用到。


?2)handler的處理

? ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

??

? ?實(shí)例化了Activity的對(duì)象:

? ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? 通過(guò)Instrumentation的newActivity方法創(chuàng)建了Activity的實(shí)體:
??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

?嘗試創(chuàng)建Application

?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程???

下面的代碼說(shuō)明了Application只存在一個(gè)實(shí)例。

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程



? 接著看performLaunchActivity方法:

??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

?


?將ContextImpl對(duì)象通過(guò)Activity的attach方法傳入到Activity

?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

最后這個(gè)也說(shuō)明了ContextWrapper里的mBase是對(duì)ContextImpl。

看官方對(duì)ContextWrapper類(lèi)解釋?zhuān)?br />

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

英文的意思是說(shuō)ContextWrapper是對(duì)Context的一種代理實(shí)現(xiàn)。



#Activity的onCreate方法回調(diào)

Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程



Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程


下面我們來(lái)細(xì)摳Activity的onCreate方法:

@MainThread
@CallSuper
protected?void?onCreate(@Nullable?Bundle?savedInstanceState)?{
????if?(DEBUG_LIFECYCLE)?Slog.v(TAG,?"onCreate?"?+?this?+?":?"?+?savedInstanceState);

????if?(getApplicationInfo().targetSdkVersion?>?O?&&?mActivityInfo.isFixedOrientation())?{
????????final?TypedArray?ta?=?obtainStyledAttributes(com.android.internal.R.styleable.Window);
????????final?boolean?isTranslucentOrFloating?=?ActivityInfo.isTranslucentOrFloating(ta);
????????ta.recycle();

????????if?(isTranslucentOrFloating)?{
????????????throw?new?IllegalStateException(
????????????????????"Only?fullscreen?opaque?activities?can?request?orientation");
????????}
????}

????if?(mLastNonConfigurationInstances?!=?null)?{
????????mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
????}
????if?(mActivityInfo.parentActivityName?!=?null)?{
????????if?(mActionBar?==?null)?{
????????????mEnableDefaultActionBarUp?=?true;
????????}?else?{
????????????mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
????????}
????}
????if?(savedInstanceState?!=?null)?{
????????mAutoFillResetNeeded?=?savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED,?false);
????????mLastAutofillId?=?savedInstanceState.getInt(LAST_AUTOFILL_ID,
????????????????View.LAST_APP_AUTOFILL_ID);

????????if?(mAutoFillResetNeeded)?{
????????????getAutofillManager().onCreate(savedInstanceState);
????????}

????????Parcelable?p?=?savedInstanceState.getParcelable(FRAGMENTS_TAG);
????????mFragments.restoreAllState(p,?mLastNonConfigurationInstances?!=?null
??????????????????mLastNonConfigurationInstances.fragments?:?null);
????}
????mFragments.dispatchCreate();
????getApplication().dispatchActivityCreated(this,?savedInstanceState);
????if?(mVoiceInteractor?!=?null)?{
????????mVoiceInteractor.attachActivity(this);
????}
????mCalled?=?true;
}
  • ?mFragments.dispatchCreate() :將onCreate事件分發(fā)給fragment,至于具體怎么分發(fā)的,后面再研究。

  • ?getApplication().dispatchActivityCreated(this, savedInstanceState) :這個(gè)方法是將activity的生命周期方法回調(diào)給Application

    ?Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

? ? ? ?

? ? ? ? 在A(yíng)pplication里即可利用這2個(gè)方法來(lái)監(jiān)聽(tīng)activity的狀態(tài):

? ? ? ??Android源碼個(gè)個(gè)擊破之Context和Activity的啟動(dòng)流程

????????這樣,不需要通過(guò)廣播,就能監(jiān)聽(tīng)到Activity的生命周期方法了。(所以不閱讀源碼,很多好用的東西發(fā)現(xiàn)不了!)


    • ?Activity的onCreate方法里會(huì)有一個(gè)mCalled變量,來(lái)判斷程序員復(fù)寫(xiě)onCreate方法是否調(diào)用了super.onCreate方法。


????????緊接著onCreate,又調(diào)用了onStart等其它的生命周期方法。

? ? ? ? 所以Activity初始創(chuàng)建的生命周期方法調(diào)用順序是:

  • attach

  • onCreate
    onStart

? ? ? 上面我們的注重點(diǎn)在于activity是如何實(shí)例化的,下面來(lái)研究一下UI方面的:Activity是怎么彈出并展示到我們的眼前的呢

? ? ? 請(qǐng)看??Android源碼個(gè)個(gè)擊破之Activity的渲染過(guò)程


??


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI