App啟動-源碼流程簡介

簡介:

在android系統(tǒng)中肴敛,Home界面也就是Launcher的界面,Launcher它本身也是一個應(yīng)用程序吗购,在其它程序安裝完成以后医男,會在Launcher中出現(xiàn)一個圖標,點擊該圖標捻勉,對應(yīng)該圖標的應(yīng)用程序也就會啟動起來镀梭。

在說明整個啟動流程之前,我們首先需要了解幾個用到的主要類:

1. ? Launcher類

Launcher俗稱HomeScreen,也就是我們啟動Android手機踱启,第一眼看到的就是這個應(yīng)用程序报账,而這個應(yīng)用程序是比較特殊而且任務(wù)艱巨的研底。它負責(zé)了我們除了應(yīng)用本身操作以外的所有操作透罢,它負責(zé)了我們有幾個桌面榜晦,點擊應(yīng)用圖標啟動應(yīng)用程序,長時間按桌面出現(xiàn)上下文菜單羽圃,長時間按桌面的圖標出現(xiàn)垃圾箱乾胶,拖動應(yīng)用圖標重新定位等等,一系列的操作朽寞。

2.? Intrumentation類

官方的解釋為:

/** Base class for implementing application instrumentation code. ?When running

* with instrumentation turned on, this class will be instantiated for you

* before any of the application code, allowing you to monitor all of the

* interaction the system has with the application. ?An Instrumentation

* implementation is described to the system through an AndroidManifest.xml's

* <instrumentation> tag.*/

大意為:Instrumentation類會在應(yīng)用的任何代碼執(zhí)行前被實列化堵幽,用來監(jiān)控系統(tǒng)與應(yīng)用的交互倔矾。

在本文介紹的啟動流程當(dāng)中,Instrumentation則搭建起了從Launcher到ActivityManagerNative橋梁,從ActivityManagerNative作為起始點竿屹,開啟了整個App啟動的流程的猛。

3.? ActivityManagerNative類

ActivityManager的功能是與系統(tǒng)中所有運行著的Activity交互提供了接口柒巫,主要的接口圍繞著運行中的進程信息胯杭,任務(wù)信息,服務(wù)信息等膜宋。而在后續(xù)的介紹中窿侈,會談到ActivityManager到ActivityManagerService之間的交互,它們二者交互中會經(jīng)過一個環(huán)節(jié)秋茫,那就是進程通信史简,而IActivityManager以及實現(xiàn)接口的代理類ActivityManagerProxy,存根類ActivityManagerNative起著負責(zé)進程通信的作用,雖然這里沒有使用aidl文件定義進程通信接口IActivityManager肛著,其實是一樣的圆兵,我們可以把它看做是自己手動編譯的aidl進程通信java類實現(xiàn),ActivityManagerProxy是代理類枢贿,ActivityManagerNative是Stub類殉农,IActivityManager是aidl接口。

4. ? ActivityStack類

正如其名局荚,ActivityStack是一個用于管理Activity棧結(jié)構(gòu)的類超凳,下面有對棧結(jié)構(gòu)的簡單介紹:

Activity承擔(dān)了大量的顯示和交互工作,從某種角度上將耀态,我們看見的應(yīng)用程序就是許多個Activity的組合轮傍。為了讓這許多 Activity協(xié)同工作而不至于產(chǎn)生混亂,Android平臺設(shè)計了一種堆棧機制用于管理Activity首装,其遵循先進后出的原則创夜,系統(tǒng)總是顯示位于棧 頂?shù)腁ctivity,從邏輯上將仙逻,位于棧頂?shù)腁ctivity也就是最后打開的Activity驰吓,這也是符合邏輯的涧尿。

在操作應(yīng)用程序時,每次啟動新的Activity檬贰,都會將此壓入Activity Stack姑廉,當(dāng)用戶執(zhí)行返回操作時,移除Activity Stack頂上的Activity偎蘸,這樣就實現(xiàn)了返回上一個Activty的功能庄蹋。直到用戶一直返回到Home Screen瞬内,這時候可以理解為移除了Activity Stack所有的Activity迷雪,這個Activity Stack不再存在,應(yīng)用程序也結(jié)束了運行虫蝶。

5. ? ActivityThread類

它管理應(yīng)用進程的主線程的執(zhí)行(相當(dāng)于普通Java程序的main入口函數(shù))章咧,并根據(jù)AMS的要求(通過IApplicationThread接口,AMS為Client能真、ActivityThread.ApplicationThread為Server)負責(zé)調(diào)度和執(zhí)行activities赁严、broadcasts和其它操作。

6. ? ActivityApplication類

該類在其它博客和論壇上有很詳細的說明粉铐,這里我們引入一些比較簡單明了的解釋:

Application和Activity,Service一樣是android框架的一個系統(tǒng)組件疼约,當(dāng)android程序啟動時系統(tǒng)會創(chuàng)建一個 application對象,用來存儲系統(tǒng)的一些信息蝙泼。通常我們是不需要指定一個Application的程剥,這時系統(tǒng)會自動幫我們創(chuàng)建,如果需要創(chuàng)建自己 的Application汤踏,也很簡單創(chuàng)建一個類繼承 Application并在manifest的application標簽中進行注冊(只需要給Application標簽增加個name屬性把自己的 Application的名字定入即可)织鲸。

android系統(tǒng)會為每個程序運行時創(chuàng)建一個Application類的對象且僅創(chuàng)建一個,所以Application可以說是單例 (singleton)模式的一個類.且application對象的生命周期是整個程序中最長的溪胶,它的生命周期就等于這個程序的生命周期搂擦。因為它是全局 的單例的,所以在不同的Activity,Service中獲得的對象都是同一個對象哗脖。所以通過Application來進行一些瀑踢,數(shù)據(jù)傳遞,數(shù)據(jù)共享 等,數(shù)據(jù)緩存等操作才避。

7. ? ActivityManagerService類

ActivityManagerService是非常值得深入學(xué)習(xí)的丘损,這里只籠統(tǒng)的說明一下他的功能:

ActivityManagerService是Android中最核心的服務(wù),主要負責(zé)系統(tǒng)中四大組件的啟動工扎、切換徘钥、調(diào)度及應(yīng)用進程的管理和調(diào)度等工作,其職責(zé)與操作系統(tǒng)中的進程管理和調(diào)度模塊相類似肢娘,因此它在Android中非常重要呈础。

額外補充:

除上面提到的信息以外舆驶,還需要對Android系統(tǒng)進程間通訊Binder機制有一定的了解,由于本文中只介紹app的啟動流程而钞,對于Binder機制沙廉,這里就從網(wǎng)上找了一些基本嘻嘻,進行簡單說明一下:

Android系統(tǒng)存了Zygote進程和SystemServer進程以及各種應(yīng)用進程等臼节,為了能夠?qū)崿F(xiàn)各種進程之間的通訊撬陵,Android系統(tǒng)采用了自己的進程間通訊方式Binder機制。其中主要涉及到了四種角色:Binder Client网缝,Binder Server巨税,Binder Manager, Binder driver粉臊。各種角色之間的關(guān)系可以參考下面這張圖的介紹:

Binder機制圖解

流程及源碼:

下面我們詳細介紹一下點擊后草添,整個源碼的運行流程:

1.Launcher:

1.a ?位于packages/apps/Launcher2目錄。

1.b ?源碼部分:

Launcher源碼

在點擊了Launcher界面中的App的圖標以后扼仲,會執(zhí)行其中的onClick方法远寸,其中intent為我們在AndroidManifest.xml文件中配置的信息:

AndroidManifest.xml配置信息

同時,從代碼中可以發(fā)現(xiàn)其中最終調(diào)用了startActivitySafely方法:

startActivitySafely方法源碼

可以發(fā)現(xiàn)內(nèi)部則又調(diào)用了startActivity方法屠凶,但是我們在Launcher類中沒有發(fā)現(xiàn)有該方法驰后,由 于Launcher類為Activity類的子類,我們可以在其父類中進行查找矗愧,發(fā)現(xiàn)其中有我們正在查找的方法:

startActivity方法源碼

它本身由調(diào)用了startActivityForResult進行處理灶芝,其中傳入的參數(shù)-1代表結(jié)束后,不需要這個Activity的結(jié)果贱枣,讓我們再來看這個startActivityForResult:

startActivityForResult方法源碼

可以發(fā)現(xiàn)监署,在startActivityForResult方法內(nèi)部,又調(diào)用了Intrumentation類的對象中的execStartActivity方法纽哥,執(zhí)行時钠乏,傳入了相應(yīng)的參數(shù),其中:

A. mMainThread:為Activity成員變量春塌,類型Activity Thread晓避,它代表的是應(yīng)用程序的主線程。

B. mMainThread.getApplicationThread():則是為了獲取其內(nèi)部的Application Thread內(nèi)部類只壳,在隨后的流程中俏拱,它作為一個Binder對象,扮演了一個鏈接通訊的角色吼句,ActivityManagerService會使用它來和ActivityThread來進行進程間通信锅必。

C. mToken:為一個Binder對象的遠程接口。

2. ?Instrumentation.execStartActivity

2.a ?作用:

它用來監(jiān)控應(yīng)用程序和系統(tǒng)的交互。

2.b ?位置:

package android.app(1492行)

2.c ?源碼:

由于在上面中調(diào)用到了Instrumentation中的execStartActivity方法搞隐,我們直接來看該方法內(nèi)部的源碼:

execStartActivity方法源碼

在方法中可以看到驹愚,與startActivity相關(guān)的方法是:ActivityManagerNative.getDefault.startActivity方法,其中:

ActivityManagerNative.getDefault返回是ActivityManagerService的遠程接口劣纲,即為ActivityManagerProxy的接口逢捺,通過該接口調(diào)用startActivity方法,在參數(shù)中可以發(fā)現(xiàn)癞季,傳入了intent.resolveTypeIfNeeded這個參數(shù)劫瞳,實則為AndroidMainfest.xml中的設(shè)置的MIME類型,從上面配置的信息中绷柒,我們可以知道intent并沒有配置MIME類型志于,因此在此返回null,不用做考慮辉巡。

3. ?ActivityManagerProxy.startActivity

3.a ?作用:

提供IActivityManager恨憎,根據(jù)參數(shù)蕊退,執(zhí)行接口中提供的對應(yīng)方法郊楣。

3.b ?位置:

ActivityManagerNative中的內(nèi)部類(3044行)

3.c ?源碼:

startActivity方法源碼

在ActivityManagerProxy的startActivity方法中,可以看見對傳入的參數(shù)及信息封裝到一個Parcel類型的Data包內(nèi)瓤荔,在封裝完成后净蚤,執(zhí)行了IBinder類型mRemote變量中的transact方法,其中傳入的對應(yīng)startActivity行為的參數(shù)START_ACTIVITY_TRANSACTION输硝。

4. ?ActivityManagerService.startActivity

4.a ?作用:

在經(jīng)過上面的mRemote變量的transact方法執(zhí)行以后今瀑,最終會通過Binder機制,進入到ActivityManagerService當(dāng)中点把,執(zhí)行startActivity方法橘荠。

4.b ?位置:

android.server.am目錄下

4.c ?源碼:

位置(4282行)

startActivity方法源碼

執(zhí)行的內(nèi)容:

最終是將操作交給了mActivityStarter中的startActivityMayWait去執(zhí)行。

5. ?ActivityStarter.startActivityMayWait

5.a ?作用:

對intent中傳來的信息進行封裝郎逃,同時調(diào)用startActivityLocked進行下一步操作哥童。

5.b ?位置:

android.server.am目錄下

5.c ?源碼:

位置:(675行)

在startActivityMayWait方法中,與啟動相關(guān)的內(nèi)容主要有:

startActivityMayWait方法源碼(1)

這部分內(nèi)容褒翰,除了在新的intent中封裝好即將啟動的應(yīng)用程序信息內(nèi)容以外贮懈,同時,調(diào)用resolveIntent方法优训,負責(zé)將intent中的內(nèi)容給解析出來朵你,得到MainActivity的相關(guān)信息,保存在ainfo變量當(dāng)中揣非。

startActivityMayWait方法源碼(2)

在最后的時候抡医,調(diào)用startActivityLocked(819行)方法去進一步處理。

6. ?ActivityStarter.startActivityLocked

6.a ?作用:

接收并保存調(diào)用者的進程信息早敬,并調(diào)用startActivityUncheckedLocked去進行下一步操作

6.b ?位置:

android.server.am目錄下

6.c ?源碼:

位置:(224行)

startActivityLocked方法源碼

startActivityLocked方法中內(nèi)部會將調(diào)用該方法的進程對象忌傻,即caller的進程信息(Launch)毛仪,保存在callerApp當(dāng)中,用于下面的ActivityRecord記錄用芯勘。

startActivityLocked方法源碼(1)

同時箱靴,作為Launcher這個Activity里面的一個Binder對象,它可以獲得LauncherActivity的相關(guān)信息荷愕,同時也被該方法的sourceRecord變量記錄了下來衡怀。

startActivityLocked方法源碼(2)

隨后,所有即將用到的進程信息會被傳入創(chuàng)建的ActivityRecord類型對象r(493行)當(dāng)中安疗。

startActivityLocked方法源碼(3)

最后調(diào)用startActivityUnchecked(535行)方法將r對象抛杨,sourceRecord等參數(shù)傳入該方法中。

7 ?ActivityStack.startActivityUnchecked等方法

7.a ?作用:

判斷即將啟動的Activity是否需要在新的task中進行創(chuàng)建和創(chuàng)建新的Task

7.b ?位置:(959行)

startActivityUnchecked方法源碼(1)

在執(zhí)行時荐类,會調(diào)用getReusableIntentActivity方法去看當(dāng)前有沒有Task可以用來執(zhí)行這個Activity怖现。

getReusableIntentActivity方法源碼

在該方法中,由于沒有在AndroidMainfest.xml中設(shè)置launchmode玉罐,因此默認情況下為0屈嗤,即standard的情況。因此在檢查時候吊输,會執(zhí)行對應(yīng)條件中的findTaskLocked方法饶号,由于這個Activity當(dāng)前都沒有創(chuàng)建過,因此季蚂,必然返回為null值茫船。

startActivityUnchecked方法源碼(2)

因此,會調(diào)用上面的setTaskFromReuseOrCreateNewTask(1091行)方法扭屁,進行Task的創(chuàng)建算谈。該方法中會將新建Task,并將新建的Task添加進TaskRecord當(dāng)中做記錄料滥。

startActivityUnchecked方法源碼(3)

最后會調(diào)用ActivityStack類型的變量mTargetStack的startActivityLocked來進行進一步處理然眼。

8 ?ActivityStack.startActivityLocked

8.a作用:

確保當(dāng)前要開啟的activity添加到新建的task的頂端。

8.b位置:(2636行)

8.c源碼:

startActivityLocked方法源碼

調(diào)用了addActivityToTop確保即將開啟的Activity被添加到Task的頂部幔欧。隨后調(diào)用resumeTopActivityInnerLocked(2113行)方法罪治。

9 ?ActivityStack.resumeTopActivityInnerLocked

9.a ?作用:

將位于當(dāng)前正在運行的LaunchActivity由Resumed狀態(tài)轉(zhuǎn)換為Paused狀態(tài)

9.b ?位置:(2113行)

9.c ?源碼:

resumeTopActivityInnerLocked方法源碼(1)

將棧頂?shù)腁ctivity取出來,這里的棧頂?shù)腁ctivity礁蔗,就是剛剛添加到棧頂MainActivity觉义,這時候取出來保存到next變量中。

resumeTopActivityInnerLocked方法源碼(2)

與當(dāng)前Activity相關(guān)的浴井,則還包括上面的判斷晒骇,mLastPausedActivity會將棧頂Activity轉(zhuǎn)換為休眠狀態(tài)時賦值給自己,而我們當(dāng)前的LaunchActivity由于仍處于Resumed狀態(tài),因此跳過本判斷洪囤,繼續(xù)往下進行徒坡。

resumeTopActivityInnerLocked方法源碼(3)

這時,由于當(dāng)前正在處于Resumed狀態(tài)下的Activity是LaunchActivity瘤缩,則此時喇完,就會走該判斷邏輯中的startPausingLocked(2252行)方法,將LaunchActivity推送到Paused狀態(tài)剥啤。

10 ?ActivityStack.startPausingLocked

10.a ?作用

將當(dāng)前處于Resumed狀態(tài)的Activity轉(zhuǎn)換為Paused狀態(tài)

10.b ?位置:(1076行)

10.c ?源碼:

startPausingLocked方法源碼(1)

當(dāng)前的LaunchActivity會作為參數(shù)賦值給prev變量锦溪。

startPausingLocked方法源碼(2)

在隨后的邏輯判斷中,由于LaunchActivity是在Zygote創(chuàng)建的時候府怯,其app及thread就被創(chuàng)建完成了刻诊,因此必然不為null,prev.app.thread為通過它來通知Launcher這個Activity它要進入Paused狀態(tài)了牺丙。當(dāng)然则涯,這里的prev.app.thread是一個ApplicationThread對象的遠程接口,通過調(diào)用這個遠程接口的schedulePauseActivity來通知Launcher進入Paused狀態(tài)冲簿。

這時就會調(diào)用ApplicationThreadProxy粟判,該代理類中的schedulePauseActivity方法。

11 ?ApplicationThreadProxy.schedulePauseActivity

11.a ?作用:

通過Binder進程間通信的機制民假,進入到ApplicationThread.schedulePauseActivity(657)方法當(dāng)中浮入。

11.b ?位置:(775行)

11.c ?源碼:

schedulePauseActivity方法源碼

該初就是將LaunchActivity的相關(guān)信息存入Parcel類型的data變量當(dāng)中龙优。最終通過Binder類型的mRemote對象運用進程間通訊的機制羊异,調(diào)用ActivityThread.schedulePauseActivity。

12 ?ActivityThread.schedulePauseActivity

12.a ?作用:

發(fā)送將LaunchActivity轉(zhuǎn)換為Paused狀態(tài)的信息彤断。

12.b ?位置:(657行)

12.c ?源碼:

schedulePauseActivity方法源碼

這里finished參數(shù)代表的是傳入的參數(shù)為prev對象所代表的Activity是否正在等待結(jié)束的Activity列表中野舶,當(dāng)前LaunchActivity當(dāng)然不在這個隊列中,還在Resumed的情況下呢宰衙。因此必然為PAUSE_ACTIVITY傳參平道,這時就可以將信息發(fā)送出去了。

13 ?ActivityThread.handleMessage.handlePauseActivity

13.a ?作用:

接收并處理發(fā)送來的信息請求

13.b ?位置:(1469行)

13.c ?源碼:

handleMessage方法源碼

根據(jù)msg傳入的what信息供炼,在handleMessage找到對應(yīng)的PAUSE_ACTIVITY項一屋。

handlePauseActivity方法源碼

在handlePauseActivity方法中,主要做了以下三件事情:

A. ?A.1 ?傳入的userLeaving值為在步驟7的方法源碼中袋哼,判斷intent標記是否有Intent.FLAG_ACTIVITY_NO_USER_ACTION冀墨,如果沒有設(shè)置,則為true涛贯。我們在AndroidMainfest.xml文件中并沒有配置诽嘉。因此此處的userLeaving為true。

? ? ?A.2 ?此時回調(diào)用performUserLeavingActivity函數(shù)來調(diào)用Activity.onUserLeaveHint通知Activity,用戶要離開它了虫腋,進行相應(yīng)操作骄酗。

B. ?調(diào)用performPauseActivity函數(shù)來調(diào)用LaunchActivity中的OnPause方法。

C. ?它通知ActivityManagerService悦冀,這個Activity已經(jīng)進入Paused狀態(tài)了ActivityManagerService現(xiàn)在可以完成未竟的事情趋翻,啟動MainActivity。

14 ?ActivityManagerProxy.activityPaused

14.a ?作用:

運行方法盒蟆,利用Binder機制執(zhí)行actiityPaused方法

14.b ?位置:(3585行)

14.c ?源碼:

actiityPaused方法源碼

看到這段代碼是不是很熟悉嘿歌,是的,在此利用了代理類來執(zhí)行了IBinder類型mRemote變量中的transact方法茁影,不過這次傳入的ACTIVITY_PAUSED_TRANSACTION字段宙帝,執(zhí)行的是pause方法。這時會會到ActivityManagerService中執(zhí)行activityPaused方法募闲。

15? ActivityManagerService.activityPausedLocked

15.a ?作用:

調(diào)用ActivityStack中的activityPausedLocked方法

15.b ?位置:(6857行)

15.c ?源碼:

activityPaused方法源碼

16 ?ActivityStack.activityPausedLocked

16.a ?作用:

執(zhí)行completePauseLocked方法

16.b ?位置:(1189行)

16.c ?源碼:

activityPausedLocked方法源碼

當(dāng)前一直在運行想要轉(zhuǎn)入Pause狀態(tài)的是LaunchActivity步脓,傳入的IBinder類型token值則對應(yīng)的就是LaunchActivity,因此mPausingActivity與r均為LaunchActivity浩螺,則執(zhí)行其中completePauseLocked方法靴患。

17 ?ActivityStack.completePauseLocked

17.a ?作用:

調(diào)用ActivityStackSupervisor中的開啟Activity方法

17.b ?位置:(1270行)

17.c ?源碼:

completePauseLocked方法源碼(1)

它主要負責(zé)了兩件事情,一件是將原來為LaunchActivity的mPausingActivity滯空要出。(1311)

completePauseLocked方法源碼(2)

另外一件事情就是調(diào)用resumeFocusedStackTopActivityLocked(1317行)方法鸳君,獲得當(dāng)前堆棧頂端的Activity,如我們之前的步驟所記患蹂,我們新建了一個task或颊,并將即將啟動的MainActivity添加到棧頂,則當(dāng)前的Activity就是我們即將要啟動的MainActivity传于,此時通過該方法囱挑,將其取出來并存儲與next當(dāng)中,然后最終調(diào)用其中的ActivityStackSupervisor中的startSpecificActivityLocked()方法沼溜,將next傳入平挑,開啟next所代表的MainActivity(2514行)。

18 ?ActivityStack.Supervisor.startSpecificActivityLocked

18.a ?作用:

判斷是否開啟該進程系草,如果沒有則調(diào)用ActivityManagerService進行開啟通熄。

18.b ?位置:(1355行)

18.c ?源碼:

startSpecificActivityLocked方法源碼(1)

在進入方法后會受限判斷該應(yīng)用是否已經(jīng)開啟,由于我們只是剛剛點開該程序找都,則取回來的app則肯定為空唇辨。

startSpecificActivityLocked方法源碼(2)

隨后就會調(diào)用ActivityManagerService.startProcessLocked方法進行下一步操作。

19 ?ActivityManagerService.startProcessLocked

19.a ?作用:

調(diào)用Process.start接口來新建一個新的進程

19.b ?位置:(3477行-3487行-3600行-3616行-3743行)

19.c ?源碼:

startProcessLocked方法部分源碼

經(jīng)過幾個方法到跳轉(zhuǎn)檐嚣,最終調(diào)用到了Process.start的方法助泽,在調(diào)用Process.start方法之前啰扛,將一個字符串entryPoint作為參數(shù)傳入到start方法中,通過該方法嗡贺,我們創(chuàng)建一個新的進程隐解,這里涉及到了Zygote中的Socket接口監(jiān)聽并調(diào)用孵化APP進程的過程,這里我們詳細說明一下:

19.c.A ? 調(diào)用Process.start方法

Process.start方法源碼

19.c.B? 內(nèi)部調(diào)用了startViaZygote方法诫睬,我們再到該方法中看一下:

startViaZygote方法部分源碼

19.c.C? 可以發(fā)現(xiàn)在其最后煞茫,又調(diào)用了zygoteSendArgsAndGetResult方法:

zygoteSendArgsAndGetResult方法部分源碼

19.c.D? 在zygoteSendArgsAndGetResult方法中,可以看到它調(diào)用了zygoteState對象(Zygote孵化完成后摄凡,開啟到監(jiān)聽Socket)续徽,并借該對象通過Socket通信機制,讓Zygote進程fork除了一個新的進程亲澡,并根據(jù)startProcessLocked方法中傳遞來的entryPoint(”android.app.ActivityThread”)字符串钦扭,反射出該對象并執(zhí)行ActivityThread的main方法。此時我們可以進入ActivityThread的main函數(shù)中看下進行了哪些操作床绪。

20 ?ActivityThread.main

20.a ?作用:

創(chuàng)建消息循環(huán)及接收處理機制客情,并最終調(diào)用ActivityManagerService中的attachApplication。

20.b ?位置:

20.c ?源碼:

main方法源碼

進程在創(chuàng)建完成以后癞己,調(diào)用了ActivityThread中的main函數(shù)膀斋,其中調(diào)用了attach函數(shù),隨后調(diào)用Looper的消息循環(huán)機制進行消息循環(huán)痹雅。

attach方法源碼

在attach方法中(5888行)仰担,通過ActivityMangerNative.getDefault方法獲得到了ActivityManager的代理類ActivityManagerProxy,調(diào)用其中的attachApplication(3544行)函數(shù)绩社。

attachApplication方法源碼

該方法中又發(fā)現(xiàn)了我們熟悉的Binder類型對象mRemote摔蓝,再次通過Binder機制,根據(jù)傳入的ATTACH_APPLICATION_TRANSACTION字段铃将,調(diào)用ActivityManagerService中的attachApplication方法(534行)项鬼。

21 ?ActivityManagerService.attachApplication

21.a ?作用:

方法調(diào)用ActivityStackSupervisor類中的attachApplicationLocked方法。

21.b ?位置:(6610行)

21.c ?源碼:

attachApplication方法源碼

內(nèi)部操作轉(zhuǎn)發(fā)給了attachApplicationLocked方法(6384行)劲阎。

attachApplicationLocked方法源碼

最終會調(diào)用位于6550行的ActivityStackSupervisor類中的attachApplicationLocked方法。

22 ?ActivityStackSupervisor.attachApplicationLocked

22.a ?作用:

將此時將啟動的MainActivity傳遞給realStartActivityLocked進行正式啟動鸠真。

22.b ?位置:(825行)

22.c ?源碼:

attachApplicationLocked方法源碼

在該方法中悯仙,可以發(fā)現(xiàn)其通過調(diào)用topRunningActivityLocked將此時位于棧頂?shù)腗ainActivity 取出來,存儲于ActivityRecord類型的hr變量中吠卷,并將hr傳遞給realStartActivityLocked方法進行開啟锡垄。

realStartActivityLocked方法源碼

通過realStartActivityLocked方法,最終通過app.thread進入到ApplicationThreadProxy的scheduleLaunchActivity函數(shù)中(709行)祭隔,注意货岭,這里的第二個參數(shù)r路操,是一個ActivityRecord類型的Binder對象,用來作來這個Activity的token值千贯。此時我們進入到ActivityThreadProxy類中進行查看屯仗。

scheduleLaunchActivity方法源碼

此方法就是將即將啟動的Activity信息進行封裝,并以LAUNCH_ACTIVITY的形式發(fā)送出去搔谴。最終交給ActivityThread中的HandleMessage進行處理魁袜。

HandleMessage方法源碼

然后再次移交給handleLaunchActivity進行處理账千。

23 ?ActivityThread.HandleMessage

23.a ?作用:

23.b ?位置:(2687行)

23.c ?源碼:

方法里主要執(zhí)行了兩個步驟:

handleLaunchActivity方法源碼

第一個步驟執(zhí)行了performLaunchActivity方法座咆,該方法加載了這個Activity類,即MainActivity大年,然后調(diào)用它的onCreate函數(shù)芜果,

第二步在回到handleLaunchActivity函數(shù)時鞠呈,再調(diào)用handleResumeActivity函數(shù)來使這個Activity進入Resumed狀態(tài),即會調(diào)用這個Activity的onResume函數(shù)右钾,這是遵循Activity的生命周期的粟按。

我們這里主要研究一下performLaunchActivity方法。

24? ActivityThread.performLaunchActivity

24.a ?作用:

保存組件信息霹粥,加載需要啟動的Activity類灭将,創(chuàng)建Application對象,并調(diào)用執(zhí)行onCreate方法

24.b ?位置:(2687行)

24.c ?源碼:

performLaunchActivity方法源碼(1)

這段代碼主要負責(zé)了收集啟動的Activity的package和component信息后控。

performLaunchActivity方法源碼(2)

這段代碼主要負責(zé)將啟動的Activity的類加載到內(nèi)存當(dāng)中

performLaunchActivity方法源碼(3)

根據(jù)AndroidMainfest.xml中配置的Application信息庙曙,創(chuàng)建Application對象。

performLaunchActivity方法源碼(4)

根據(jù)記錄到ActivityRecord中的信息浩淘,設(shè)置Activity中的配置信息捌朴,以及上下文信息等

performLaunchActivity方法源碼(5)

最后通過mInstrumentation的callActivityOnCreate函數(shù)來間接調(diào)用,前面我們說過张抄,mInstrumentation在這里的作用是監(jiān)控Activity與系統(tǒng)的交互操作砂蔽,相當(dāng)于是系統(tǒng)運行日志。

到這里署惯,從點擊app到啟動app執(zhí)行onCreate方法到一整個流程就進行完畢了左驾。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市极谊,隨后出現(xiàn)的幾起案子诡右,更是在濱河造成了極大的恐慌,老刑警劉巖轻猖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帆吻,死亡現(xiàn)場離奇詭異,居然都是意外死亡咙边,警方通過查閱死者的電腦和手機猜煮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門次员,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人王带,你說我怎么就攤上這事淑蔚。” “怎么了辫秧?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵束倍,是天一觀的道長。 經(jīng)常有香客問我盟戏,道長绪妹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任柿究,我火速辦了婚禮邮旷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蝇摸。我一直安慰自己婶肩,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布貌夕。 她就那樣靜靜地躺著律歼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啡专。 梳的紋絲不亂的頭發(fā)上险毁,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音们童,去河邊找鬼畔况。 笑死,一個胖子當(dāng)著我的面吹牛慧库,可吹牛的內(nèi)容都是我干的跷跪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼齐板,長吁一口氣:“原來是場噩夢啊……” “哼吵瞻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起覆积,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤听皿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宽档,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡庵朝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年吗冤,在試婚紗的時候發(fā)現(xiàn)自己被綠了又厉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡椎瘟,死狀恐怖覆致,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肺蔚,我是刑警寧澤煌妈,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站宣羊,受9級特大地震影響璧诵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仇冯,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一之宿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧苛坚,春花似錦比被、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至娇昙,卻和暖如春尺迂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涯贞。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工枪狂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宋渔。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓州疾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親皇拣。 傳聞我的和親對象是個殘疾皇子严蓖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容