常見基礎問題:
SystemServer系統服務行程是如何創建的?Launcher行程如何被創建的?
是由Zygote行程fork而來
Launcher啟動入口在哪兒?
ActivityManagerService的systemReady函式就是啟動Launcher的入口,
系統如何識別Launcher應用?
android.intent.category.HOME
如何開發一個桌面Launcher應用?
android.intent.category.HOME;
android.intent.category.DEFAUlT,
Android應用行程的的入口類?
ActivityThread
為什么Activity必須在清單檔案中注冊?
ActivityStarter會做各種啟動前檢查,
一、Android系統架構及開機流程
Google官方提供的經典分層架構圖:

從下往上依次分為5層:
- Linux內核層
- HAL層(硬體抽象層)
- 系統運行庫層(系統Native庫和Android運行時環境)
- FramWork層(Java框架層)
- Application層(包括Systema Apps和三方App)
Google提供的5層架構圖很經典,但為了更進一步透視Android系統架構,本文更多的是以行程的視角,以分層的架構來詮釋Android系統的全貌,闡述Android內部的環環相扣的內在聯系,如下為:系統啟動架構圖

首先,關于Android手機開機的程序,Loader層:
Boot ROM: 當手機處于關機狀態時,長按Power鍵開機,引導芯片開始從固化在ROM里的預設代碼開始執行,然后加載引導程式到RAM;
Boot Loader:這是啟動Android系統之前的引導程式,主要是檢查RAM,初始化硬體引數,拉起Android OS,
圖解: Android系統啟動程序由上圖從下往上的一個程序是由Boot Loader引導開機,然后依次進入 -> Linux Kernel -> Native -> Framework -> App,接來下簡要說說每個程序:
Linux內核層:
Android平臺的基礎是Linux內核,比如ART虛擬機最終呼叫底層Linux內核來執行功能,Linux內核的安全機制為Android提供相應的保障,也允許設備制造商為內核開發硬體驅動程式,
啟動Kernel的swapper行程(pid=0):該行程又稱為idle行程, 系統初始化程序Kernel由無到有開創的第一個行程, 用于初始化行程管理、記憶體管理,加載Display,Camera Driver,Binder Driver等相關作業;
啟動kthreadd行程(pid=2):是Linux系統的內核行程,會創建內核作業執行緒kworkder,軟中斷執行緒ksoftirqd,thermal等內核守護行程,kthreadd行程是所有內核行程的鼻祖,
硬體抽象層 (HAL):
硬體抽象層 (HAL) 提供標準介面,HAL包含多個庫模塊,其中每個模塊都為特定型別的硬體組件實作一組介面,比如WIFI/藍牙模塊,當框架API請求訪問設備硬體時,Android系統將為該硬體加載相應的庫模塊,
系統運行庫層:
每個應用都在其自己的行程中運行,都有自己的虛擬機實體,ART通過執行DEX檔案可在設備運行多個虛擬機,DEX檔案是一種專為Android設計的位元組碼格式檔案,經過優化,使用記憶體很少,ART主要功能包括:預先(AOT)和即時(JIT)編譯,優化的垃圾回收(GC),以及除錯相關的支持,
這里的Native系統庫主要包括init范訓來的用戶空間的守護行程、HAL層以及開機影片等,啟動init行程(pid=1),是Linux系統的用戶行程,init行程是所有用戶行程的鼻祖,
Framework層:
Zygote行程,是由init行程通過決議init.rc檔案后fork生成的,Zygote行程主要包含:
加載ZygoteInit類,注冊Zygote Socket服務端套接字
加載虛擬機
提前加載類preloadClasses
提前加載資源preloadResouces
SystemServer系統服務行程,是由Zygote行程fork而來,System Server是Zygote范訓的第一個行程,System Server負責啟動和管理整個Java framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服務,
Media Server行程,是由init行程fork而來,負責啟動和管理整個C++ framework,包含AudioFlinger,Camera Service等服務,
Application層:
Zygote行程范訓出的第一個App行程是Launcher,這是用戶看到的桌面App;
Zygote行程還會創建Browser,Phone,Email等App行程,每個App至少運行在一個行程上,
所有的App行程都是由Zygote行程fork生成的,
二、Android系統中極其重要的行程:
init行程, Zygote行程, SystemServer行程, ServiceManager行程,
2.1.init行程
Init行程是Android啟動的第一個行程,行程號為1(pid=1),是Android 的系統啟動的核心行程,主要用來創建Zygote、屬性服務等, init.cpp 中的main 函式,是init行程的入口函式,原始碼主要存在\system\core\init目錄下,
重點:它是Linux系統中用戶空間的第一個行程,由于Android是基于Linux內核的,所以init也是Android系統中用戶空間的第一個行程,

init行程會范訓出ueventd、logd、healthd、installd、adbd、lmkd等用戶守護行程(守護行程一般以d結尾);
init提供property service(屬性服務)來管理Android系統的屬性,
init行程還啟動servicemanager(binder服務管家)、bootanim(開機影片)等重要服務
init行程范訓出Zygote行程,Zygote行程是Android系統的第一個Java行程(即虛擬機行程),Zygote是所有Java行程的父行程,Zygote行程本身是由init行程范訓而來的,
Linux Kernel完成系統設定后,會首先在系統中尋找init.rc檔案,并啟動init行程,
由于init中都是C語言代碼,看不懂,不深入看原始碼了,簡單了解下啟動zygote的部分,在init.zygote.rc檔案中,zygote服務定義如下:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
通過init_parser.cpp完成整個service決議作業,此處就不詳細展開講決議程序,該程序主要作業是:
創建一個名叫”zygote”的service結構體;
創建一個用于socket通信的socketinfo結構體;
創建一個包含4個onrestart的action結構體,
Zygote服務會隨著main class的啟動而啟動,退出后會由init重啟zygote,即使多次重啟也不會進入recovery模式,zygote所對應的可執行檔案是/system/bin/app_process,通過呼叫pid =fork()創建子行程,通過execve(svc->args[0], (char**)svc->args, (char**) ENV),進入App_main.cpp的main()函式,故zygote是通過fork和execv共同創建的,
2.2.Zygote行程
在Zygote行程創建完成之后,會進入java世界,即ZygoteInit.java,
問:我們知道Java呼叫C++可以通過JNI,那么C++是如何轉到Java的,也就是說ZygoteInit.java這個類是如何被呼叫的?
答:在java中,class檔案是由ClassLoader來加載的,但實際上,ClassLoader在加載java檔案的程序中,也是通過C++來完成的(Bootstrp loader就是用C++寫的,具體可以去看java類加載程序及機制,Java類加載器ClassLoader總結),所以C++如果想要訪問java檔案的話,是非常輕松的,如下:

接下里看ZygoteInit.java都做了些什么

這里第一步預加載的有系統的class檔案,系統的資源檔案,系統的動態庫,因為我們所開發的應用在運行時會使用到大量的系統資源,如果這些資源在app啟動的時候才加載,勢必會造成app啟動緩慢,而如果在Android系統啟動的時候就將這些資源提前預加載,就可以達到提高啟動app速度,
第三步這里的Socket服務是用來接受來自ActivityManagerService申請行程創建的請求的,然后就會進入到阻塞狀態,等待連接,
SystemServer行程創建后會做什么,看一下SystemServer.java這個類(抽取最核心的代碼):

在SystemServer的入口mian方法中,啟動了非常多的服務,這些服務都交給SystemServerManager來管理,

其中其它服務一共有90+,這些服務都是通過startService方式啟動,并注冊到SystemServerManager當中的,如:

這些系統服務就構成了Android的FramWork層,為上層的app開發和運行提供了保障,所以SystemServer這個行程是在系統的啟動流程中,我們需要重點了解的,
當這些服務啟動完成之后;其中的ActivityManagerService最侄訓呼叫systemReady()方法,

注意systemReady這個方法,注釋的意思大概是:我們是時候去通知ActivityManager去啟動第三方應用了,當三方應用真的可以運行的時候會通知我們,以便我們完成初始化,括號里面的內容大概是:在它(三方應用)啟動之前會先啟動launcher應用,
Android 系統啟動流程總結:
第一步:手機開機后,引導芯片啟動,引導芯片開始從固化在ROM里的預設代碼執行,加載引導程式到到RAM,BootLoader檢查RAM,初始化硬體引數等功能;
第二步:硬體等引數初始化完成后,進入到Kernel層,Kernel層主要加載一些硬體設備驅動,初始化行程管理等操作,在Kernel中首先啟動swapper行程(pid=0),用于初始化行程管理、內管管理、加載Driver等操作,再啟動kthread行程(pid=2),這些linux系統的內核行程,kthread是所有內核行程的鼻祖;
第三步:Kernel層加載完畢后,硬體設備驅動與HAL層進行互動,初始化進程管理等操作會啟動init行程 ,這些在Native層中;
第四步:init行程(pid=1,init行程是所有行程的鼻祖,第一個啟動)啟動后,會啟動adbd,logd等用戶守護行程,并且會啟動servicemanager(binder服務管家)等重要服務,同時范訓出zygote行程,這里屬于C++ Framework,代碼為C++程式;
第五步:zygote行程是由init行程決議init.rc檔案后fork生成,它會加載虛擬機,啟動System Server(zygote范訓的第一個行程);SystemServer負責啟動和管理整個Java Framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服務;
第六步:zygote同時會啟動相關的APP行程,它啟動的第一個APP行程為Launcher,然后啟動Email,SMS等行程,所有的APP行程都有zygote fork生成,
到這里,系統開機到桌面應用準備就完成了,接下來就是launcher應用啟動流程分析,
三、Launcher啟動流程
3.1.Launcher啟動流程關鍵類介紹:
ActivityManagerService:
負責管理四大組件和行程,包括生命周期和狀態切換,它的systemReady()方法,正是launcher應用啟動的入口,
ActivityTaskManagerService:
把原先在ActivityManagerService中負責Activity管理和調度等作業轉移到了這里,ActivityTaskManagerService是Android10中新增的,
RootActivityContainer:
呼叫packageManagerService中去查詢手機系統中已安裝的所有的應用,哪一個符合launcher標準,且得到一個Intent物件,并交給ActivityStarter,
ActivityStarter:
做啟動之前的各項檢查,比如Activity是否有在清單檔案注冊,Class檔案是否存在等等,
ActivityRecord:
在Server端對activity的一種映射,記錄和存盤activity的資訊,
TaskRecord:
記錄一個或多個ActivityRecord的實體
ActivityStack:
應用的任務堆疊的管理者
ActivityStackSupervisor:
負責所有Activity堆疊的管理,包括launcher和非launcher應用,
ProcessList:
把原先在AMS中啟動行程的作業轉移到這里,是Android10中新增的,
Instrumentation:
負責呼叫Activity和Application生命周期,
ActivityTaskManagerInternal:
是由ActivityTaskManagerService對外提供的一個抽象類,真正的實作是在 ActivityTaskManagerService#LocalService
ActivityThread:
管理應用程式行程中主執行緒的執行
TransactionExecutor:
主要作用是執行ClientTransaction
ClientLifecycleManager:
生命周期的管理呼叫
3.2.launcher啟動流程分析:
Launcher的啟動由三部分啟動:
1.SystemServer完成啟動Launcher Activity(符合launcher應用的最佳Activity)的呼叫
2.Zygote fork出launcher行程,
3.ActivityThread的main()方法,完成最終Launcher的onCreate操作
3.2.1.第一階段:SystemServer啟動Launcher應用呼叫階段
呼叫堆疊如下:

前面我們知道了ActivityManagerService的systemReady()正是Launcher啟動的入口,在其中會去呼叫startHomeOnAllDisplays()來啟動Launcher.
[ActivityManagerService.java]
public void systemReady(final Runnable goingCallback, TimingsTraceLog
traceLog) {
...
//啟動HomeActivity:本意是在所有的螢屏上啟動桌面應用,因為Android10.0開始是支持多螢屏的,比如手機螢屏,虛擬投屏,外界螢屏
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
...
}
這里的mAtmInternal.startHomeOnAllDisplays(),mAtmInternal是ActivityTaskManagerInternal,是一個抽象類

真正的實作是在ActivityTaskManagerService的內部類LocalService中,
這里有個閱讀原始碼的技巧,一般以Internal結尾的抽象類,其實作類如下圖所示,都在內部類LocalService中,

然后找到ActivityTaskManagerService的LocalService,它繼承自ActivityManagerInternal,確實有startHomeOnAllDisplays()方法,這里最終呼叫到RootActivityContainer 的startHomeOnDisplay()方法

前面提到RootActivityContainer的作用是:呼叫packageManagerService中去查詢手機系統中已安裝的所有的應用,哪一個符合launcher標準,且得到一個Intent物件,并交給ActivityStarter,
這里會一直呼叫到RootActivityContainer.startHomeOnDisplay()方法:
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
...
if (displayId == DEFAULT_DISPLAY) {
//關鍵點1:構建一個category為CATEGORY_HOME的Intent,表明是HomeActivity(我覺得這個說法太含混,應該表明是構建一個符合launcher應用的Intent)
homeIntent = mService.getHomeIntent();
//關鍵點2:通過PMS從系統所用已安裝的參考中,找到一個符合homeIntent的Activity
aInfo = resolveHomeActivity(userId, homeIntent);
}
...
//關鍵點3:啟動launcher
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}
獲取的displayId為DEFAULT_DISPLAY, 通過getHomeIntent 來構建一個category為CATEGORY_HOME的Intent,表明是一個符合launcher應用的Intent;然后通過resolveHomeActivity()從系統所用已安裝的參考中,找到一個符合該Intent的Activity,最終呼叫startHomeActivity()來啟動Activity
然后看下ActivityTaskManagerService.getHomeIntent()方法:主要就是構建一個
符合launcher應用的Intent,
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//不是生產模式,add一個CATEGORY_HOME
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);//表明是符合launcher的Intent
}
return intent;
RootActivityContainer.resolveHomeActivity()方法:
ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
final int flags = ActivityManagerService.STOCK_PM_FLAGS;
final ComponentName comp = homeIntent.getComponent(); //系統正常啟動時,component為null
ActivityInfo aInfo = null;
...
if (comp != null) {
// Factory test.
aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
} else {
//系統正常啟動時,走該流程
final String resolvedType =
homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
//resolveIntent做了兩件事:1.通過queryIntentActivities來查找符合HomeIntent需求Activities
//2.通過chooseBestActivity找到最符合Intent需求的Activity資訊
final ResolveInfo info = AppGlobals.getPackageManager()
.resolveIntent(homeIntent, resolvedType, flags, userId);
if (info != null) {
aInfo = info.activityInfo;
}
}
...
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
return aInfo;
}
通過Binder跨行程通知PackageManagerService從系統所用已安裝的參考中,找到一個符合HomeItent的Activity,
然后是ActivityStartController.startHomeActivity()方法:
這個類唯一的作用就是配置activity啟動前的一些資訊,并把這些資訊傳遞給ActivityStart去做啟動,
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
....
//關鍵點:obtainStarter方法回傳一個 ActivityStarter物件,它負責 Activity 的啟動
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute(); // 關鍵點:execute()會觸發 ActivityStarter的execute方法
mLastHomeActivityStartRecord = tmpOutRecord[0];
final ActivityDisplay display =
mService.mRootActivityContainer.getActivityDisplay(displayId);
final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
if (homeStack != null && homeStack.mInResumeTopActivity) {
//如果home activity 處于頂層的resume activity中,則Home Activity 將被初始化,但不會被恢復(以避免遞回恢復),
//并將保持這種狀態,直到有東西再次觸發它,我們需要進行另一次恢復,
mSupervisor.scheduleResumeTopActivities();
}
}
ActivityStarter.execute()方法:
int execute() {
...
if (mRequest.mayWait) {
return startActivityMayWait(...)
} else {
return startActivity(...)
}
...
}
由于obtainStarter方法沒有呼叫setMayWait的方法做任何配置,因此mRequest.mayWait為false,會走startActivity流程
ActivityStarter. startActivity()方法:

這個方法主要用來做activity啟動之前的安全校驗
關鍵點:int err = ActivityManager.START_SUCCESS

這里的caller,只有當應用行程創建完成之后,Server端才能拿到這個物件不為空的值,由于此時launcher應用的行程還未創建,所以此時caller物件一定為空,
還會做一些其它的校驗,包括后臺啟動activity,activity啟動權限等,其它如:

接著會呼叫到ActivityStarter.startActivityUnchecked方法

其中computeLaunchingTaskFlags(),是根據activity的launcher mode和intent.flag計算出activity的入堆疊方式,computeSourceStack()計算從哪個任務堆疊啟動該activity,
這個方法一路會呼叫到
RootActivityContainer.resumeFocusedStacksTopActivities()方法:
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
//如果秒表堆疊就是堆疊頂Activity,啟動resumeTopActivityUncheckedLocked()
if (targetStack != null && (targetStack.isTopStackOnDisplay()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
...
if (!resumedOnDisplay) {
// 獲取堆疊頂的ActivityRecord
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
//最終呼叫startSpecificActivityLocked()
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
}
中間還會走到ActivityStack中呼叫方法,如:

由于此時launcher行程沒有創建完成,所以走到else中,然后呼叫到

接著看ActivityStackSupervisor.startSpecificActivityLocked()
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
...
//最終呼叫到AMS的startProcess()
final Message msg = PooledLambda.obtainMessage(
//這里的::是java8中的一個關鍵字,主要解決java8之前方法不能作為其它方法引數的問題
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
...
}
ActivityManagerService.startProcess()方法:開始創建行程

然后呼叫startProcessLocked方法,

在startProcessLocked中,又進一步把行程創建作業委派給了ProcessList,這是Android10中對FrameWork進行改造而引入的,在老的版本中對行程的創建是在AMS中去發起請求的,谷歌團隊認為AMS已經非常臃腫了(改造前2.8W行,改造后1.9W行),所以引入ProcessList專門進行行程的創建,
接著看ProcessList.startProcessLocked方法:

主要作用是,在行程創建之前,會配置一些必要的引數,比如版本號之類的,
接著,這個方法中有一個非常重要的引數:

entryPoint就是新行程的入口,
在創建行程的時候,在這里強制指定為android.app.ActivityThread.
所以,所有Android應用的行程入口是ActivityThread,并不是我們通常理解的application,
創建行程所需要的引數配置完成后,最侄訓走到ZygoteProcess

此時還是處于SystemServer行程,這個類的目的是創建本地socket連接物件,并且連接遠在Zygote行程的socket服務,然后通過字符輸入流,把創建行程所需要的引數發送過去,行程創建完成后,會根據傳遞的新行程的入口類,由zygotInit反射執行,
創建行程的呼叫堆疊如下:

3.2.2.第二階段:Zygote fork一個Launcher行程的階段
Zygote的啟動程序我們前面有簡單了解,SystemServer的AMS服務向啟動launcher發起一個fork請求,Zygote行程通過Linux的fork函式,范訓出一個新的行程,
由于Zygote行程在啟動時會創建Java虛擬機,因此通過fork而創建的Launcher程式行程可以在內部獲取一個Java虛擬機的實體拷貝,fork采用copy-on-write機制,有些類如果不做改變,甚至都不用復制,子行程可以和父行程共享這部分資料,從而省去不少記憶體的占用,
Zygote的呼叫堆疊如下:

ZygoteInit.main():
public static void main(String argv[]) {
...
Runnable caller;
....
if (startSystemServer) {
//Zygote Fork出的第一個行程 SystmeServer
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
...
//回圈等待fork出其他的應用行程,比如Launcher
//最終通過呼叫processOneCommand()來進行行程的處理
caller = zygoteServer.runSelectLoop(abiList);
...
if (caller != null) {
caller.run(); //執行回傳的Runnable物件,進入子行程
}
}
Zygote先fork出SystemServer行程,接著進入回圈等待,用來接收Socket發來的訊息,用來fork出其他應用行程,比如Launcher,
ZygoteConnection.processOneCommand():
Runnable processOneCommand(ZygoteServer zygoteServer) {
int pid = -1;
...
//Fork子行程,得到一個新的pid
/fork子行程,采用copy on write方式,這里執行一次,會回傳兩次
///pid=0 表示Zygote fork子行程成功
//pid > 0 表示子行程 的真正的PID
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
...
if (pid == 0) {
// in child, fork成功,第一次回傳的pid = 0
...
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
//in parent
...
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
}
通過forkAndSpecialize()來fork出Launcher的子行程,并執行handleChildProc,進入子行程的處理.
ZygoteConnection.handleChildProc():
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.mInvokeWith != null) {
...
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
// App行程將會呼叫到這里,執行目標類的main()方法
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
進行子行程的操作,最侄訓得需要執行的ActivityThread的main()
然后把之前傳來的"android.app.ActivityThread" 傳遞給findStaticMain:
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
// startClass: 如果AMS通過socket傳遞過來的是 ActivityThread
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
通過反射,拿到ActivityThread的main()方法:
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
return new MethodAndArgsCaller(m, argv);
}
把反射得來的ActivityThread main()入口回傳給ZygoteInit的main,通過caller.run()進行呼叫:
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
//呼叫ActivityThread的main()
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
到這里,就執行到了ActivityThread的main()方法,
3.2.3.第三階段:進入ActivityThread的main(),完成最終Launcher的onCreate操作
Zygote fork出了Launcher的行程,并把接下來的Launcher啟動任務交給了ActivityThread來進行,接下來我們就從ActivityThread main()來分析Launcher的創建程序,

ActivityThread.main():Java程式的入口,直接找到main方法,
public static void main(String[] args) {
...
//初始化looper
Looper.prepareMainLooper();
...
ActivityThread thread = new ActivityThread();
//建立Binder通道 (創建新執行緒)
thread.attach(false, startSeq);
...
//主執行緒開始輪訓,如果退出,說明程式關閉
Looper.loop();
}
正式因為在行程的入口方法里面開始了訊息佇列的輪訓,所以主執行緒才有了訊息分發的機制,
ActivityThread的attach會一直呼叫到AMS的attachApplication方法,
ActivityManagerService.attachApplication():
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
//通過Binder獲取傳入的pid資訊
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
...
...
}
}
在這個方法中,又呼叫一系列方法,這里省略大量代碼,最終主要做了兩件事:
1.調度ActivityThread創建Application,并呼叫了application的onCreate()方法,如圖:

2.繼續啟動行程創建之前已經加入任務堆疊的那個Activity,也就是Launcher應用的第一個Activity,
mAtmIntetnal.attachApplication(…),這里的mAtmIntetnal是ActivityTaskManagerInternal,這個方法的作用就是啟動launcher應用的第一個Activity,根據前面講的閱讀原始碼技巧,這里可以找到該方法的實作在ActivityTaskManagerService中:

這里進一步交給了RootActivityContainer,接著看,這里很關鍵:

終于層層呼叫到ActivityStackSupervisor.java的 **realStartActivityLocked()**進行Activity的啟動了,
ActivityStackSupervisor.realStartActivityLocked():
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
try {
//創建一個啟動Activity的事務物件
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
//往事務里面添加一個任務,叫LaunchActivityItem
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
...
final ActivityLifecycleItem lifecycleItem;
//這里就是上面提到的andResume引數,只有當該Activity在堆疊頂才為True.
if (andResume) {
//執行Activity的resume生命周期方法
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
//執行Activity的pause生命周期方法
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
//開始事務的執行
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
這里的LaunchActivityItem,ResumeActivityItem等也是在Android10.0的改動,把Activity的生命周期拆分成ActivityLifecycleItem,根據不同的狀態讓不同的ActivityLifecycleItem去執行不同的activity的生命周期,這種設計模式叫做狀態機,

在狀態機模式中,將每一個條件的分支,放入一個獨立的類中,去除過多的 if else 分支陳述句,
接著看上面,一旦執行了scheduleTransaction開啟事務,就會呼叫到LaunchActivityItem的excute方法,然后會呼叫到ClientTranscationHandler的handlerLaunchActivity方法,

我們知道ClientTranscationHandler是ActivityThread的父類,是一個抽象類,所以直接找到ActivityThread中去查看,在ActivityThread的handlerLaunchActivity中又會呼叫到performLaunchActivity方法:

這個方法就會去真正的啟動Activity,并且回傳一個Activity物件,當得到這個Activity的實體物件之后,接著看該方法下面的代碼:

跟進這個方法:
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity); //activity onCreate的預處理
activity.performCreate(icicle, persistentState);//執行onCreate()
postPerformCreate(activity); //activity onCreate創建后的一些資訊處理
}
performCreate()主要呼叫Activity的onCreate():
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
同理:如果還往事務中添加了ResumeActivityItem,相應的也會執行到Activity的onResume生命周期,
好了,到這里終于看到我們熟悉的Activity的onCreate(),到這里Launcher應用才啟動完成,Launcher被真正創建起來,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/262075.html
標籤:其他
上一篇:實作聯系人功能,右側A~Z滑動
