摘要:上一節我們講完了Android10.0的ActivityManagerService的啓動流程,在AMS的最後啓動了Launcher進程,今天我們就來看看Launcher的真正啓動流程。
閱讀本文大約需要花費50分鐘。
文章的內容主要還是從源碼進行分析,雖然又臭又長,但是如果想要學習Android系統源碼,這是必要走的路,沒有捷徑。
相對於碎片學習,我更傾向於靜下心來花費1個小時認真的學習一段內容。
文章首發微信公衆號:IngresGe
專注於Android系統級源碼分析,Android的平臺設計,歡迎關注我,謝謝!
[Android取經之路] 的源碼都基於Android-Q(10.0) 進行分析
[Android取經之路] 系列文章:
《系統啓動篇》
- Android系統架構
- Android是怎麼啓動的
- Android 10.0系統啓動之init進程
- Android10.0系統啓動之Zygote進程
- Android 10.0 系統啓動之SystemServer進程
- Android 10.0 系統服務之ActivityMnagerService
- Android10.0系統啓動之Launcher(桌面)啓動流程
- Android10.0應用進程創建過程以及Zygote的fork流程
- Android 10.0 PackageManagerService(一)工作原理及啓動流程
- Android 10.0 PackageManagerService(二)權限掃描
- Android 10.0 PackageManagerService(三)APK掃描
- Android 10.0 PackageManagerService(四)APK安裝流程
《日誌系統篇》
- Android10.0 日誌系統分析(一)-logd、logcat 指令說明、分類和屬性
- Android10.0 日誌系統分析(二)-logd、logcat架構分析及日誌系統初始化
- Android10.0 日誌系統分析(三)-logd、logcat讀寫日誌源碼分析
- Android10.0 日誌系統分析(四)-selinux、kernel日誌在logd中的實現
《Binder通信原理》:
- Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
- Android10.0 Binder通信原理(二)-Binder入門篇
- Android10.0 Binder通信原理(三)-ServiceManager篇
- Android10.0 Binder通信原理(四)-Native-C\C++實例分析
- Android10.0 Binder通信原理(五)-Binder驅動分析
- Android10.0 Binder通信原理(六)-Binder數據如何完成定向打擊
- Android10.0 Binder通信原理(七)-Framework binder示例
- Android10.0 Binder通信原理(八)-Framework層分析
- Android10.0 Binder通信原理(九)-AIDL Binder示例
- Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub設計模式
- Android10.0 Binder通信原理(十一)-Binder總結
1.概述
上一節我們學習了AMS\ATM的啓動流程,這一節主要來學習Launcher的啓動流程。
在Android的中,桌面應用Launcher由Launcher演變到Launcher2,再到現在的Launcher3,Google也做了很多改動。
Launcher不支持桌面小工具動畫效果,Launcher2添加了動畫效果和3D初步效果支持,從Android 4.4 (KK)開始Launcher默認使用Launcher3, Launcher3加入了透明狀態欄,增加overview模式,可以調整workspace上頁面的前後順序,可以動態管理屏幕數量,widget列表與app list分開顯示等功能。
我們主要研究Launcher3的啓動過程。
2.核心源碼
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
/frameworks/base/core/java/android/os/Process.java
/frameworks/base/core/java/android/os/ZygoteProcess.java
/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/Activity.java
/frameworks/base/core/java/android/app/ActivityManagerInternal.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
/frameworks/base/core/java/android/app/Instrumentation.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
從上面的代碼路徑可以看出,Android10.0中 Activity的相關功能被放到了wm的目錄中,在Android9.0中是在am目錄中,Google 最終的目的是把activity 和window融合,在Android10中只是做了簡單的代碼路徑的變更,正在的功能還要到後面的版本才能慢慢融合。
主要代碼作用:
- Instrumentation:
負責調用Activity和Application生命週期。
- ActivityTaskManagerService:
負責Activity管理和調度等工作。
ATM是Android10中新增內容
- ActivityManagerService:
負責管理四大組件和進程,包括生命週期和狀態切換。
- ActivityTaskManagerInternal:
是由ActivityTaskManagerService對外提供的一個抽象類,真正的實現是在 ActivityTaskManagerService#LocalService
- ActivityThread:
管理應用程序進程中主線程的執行
- ActivityStackSupervisor:
負責所有Activity棧的管理
- TransactionExecutor:
主要作用是執行ClientTransaction
- ClientLifecycleManager:
生命週期的管理調用
3.架構
Android啓動流程圖:
Launcher啓動序列圖:
內容較多,例如Zygote的fork流程,realStartActivityLocked啓動Activity的中間過程,都沒有列出,下一個章節會單獨來講這部分內容
4.源碼分析
上一節在AMS啓動過程中,我們知道了AMS啓動完成前,在systemReady()中會去調用startHomeOnAllDisplays()來啓動Launcher,本次就從startHomeOnAllDisplays()函數入口,來看看Launcher是如何被啓動起來的。
[ActivityManagerService.java]
public void systemReady(final Runnable goingCallback, TimingsTraceLog
traceLog) {
...
//啓動Home Activity
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
...
}
Launcher的啓動由三部分啓動:
-
SystemServer完成啓動Launcher Activity的調用
-
Zygote()進行Launcher進程的Fork操作
-
進入ActivityThread的main(),完成最終Launcher的onCreate操作
接下來我們分別從源碼部分來分析這三個啓動過程。
4.1第一階段SystemServer 啓動HomeActivity的調用階段
調用棧:
[ActivityTaskManagerService.java] startHomeOnAllDisplays()
說明:ActivityTaskManagerInternal是 ActivityTaskManagerService的一個抽象類,正在的實現是在ActivityTaskManagerService的LocalService,所以mAtmInternal.startHomeOnAllDisplays()最終調用的是ActivityTaskManagerService的startHomeOnAllDisplays()方法
源碼:
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
//一路調用到 RootActivityContainer 的startHomeOnDisplay()方法,參考[4.2]
return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
}
}
4.2 [RootActivityContainer.java] startHomeOnDisplay()
說明:在[4.1]中,獲取的displayId爲DEFAULT_DISPLAY, 首先通過getHomeIntent 來構建一個category爲CATEGORY_HOME的Intent,表明是Home Activity;然後通過resolveHomeActivity()從系統所用已安裝的引用中,找到一個符合HomeItent的Activity,最終調用startHomeActivity()來啓動Activity
源碼:
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
...
if (displayId == DEFAULT_DISPLAY) {
//構建一個category爲CATEGORY_HOME的Intent,表明是Home Activity,參考[4.2.1]
homeIntent = mService.getHomeIntent();
//通過PKMS從系統所用已安裝的引用中,找到一個符合HomeItent的Activity參考[4.2.2]
aInfo = resolveHomeActivity(userId, homeIntent);
}
...
//啓動Home Activity,參考[4.3]
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}
4.2.1 [ActivityTaskManagerService.java] getHomeIntent()
說明:構建一個category爲CATEGORY_HOME的Intent,表明是Home Activity。
Intent.CATEGORY_HOME = "android.intent.category.HOME"
這個category會在Launcher3的 AndroidManifest.xml中配置,表明是Home Acivity
源碼:
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);
}
return intent;
}
4.2.2 [RootActivityContainer.java] resolveHomeActivity()
說明:通過Binder跨進程通知PackageManagerService從系統所用已安裝的引用中,找到一個符合HomeItent的Activity
源碼:
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;
}
4.3 [ActivityStartController.java ] startHomeActivity()
說明:正在的啓動Home Activity入口。obtainStarter() 方法返回的是 ActivityStarter 對象,它負責 Activity 的啓動,一系列 setXXX() 方法傳入啓動所需的各種參數,最後的 execute() 是真正的啓動邏輯。另外如果home activity處於頂層的resume activity中,則Home Activity 將被初始化,但不會被恢復。並將保持這種狀態,直到有東西再次觸發它。我們需要進行另一次恢復。
源碼:
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
....
//返回一個 ActivityStarter 對象,它負責 Activity 的啓動
//一系列 setXXX() 方法傳入啓動所需的各種參數,最後的 execute() 是真正的啓動邏輯
//最後執行 ActivityStarter的execute方法
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute(); //參考[4.3.1]
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();
}
}
4.3.1 [ActivityStarter.java] execute()
說明:在[4.3]中obtainStarter沒有調用setMayWait的方法,因此mRequest.mayWait爲false,走startActivity流程
源碼:
int execute() {
...
if (mRequest.mayWait) {
return startActivityMayWait(...)
} else {
return startActivity(...) //參考[4.3.2]
}
...
}
4.3.2 [ActivityStarter.java] startActivity()
說明:延時佈局,然後通過startActivityUnchecked()來處理啓動標記 flag ,要啓動的任務棧等,最後恢復佈局
源碼:
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
...
try {
//延時佈局
mService.mWindowManager.deferSurfaceLayout();
//調用 startActivityUnchecked ,一路調用到resumeFocusedStacksTopActivities(),參考[4.3.4]
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
} finally {
//恢復佈局
mService.mWindowManager.continueSurfaceLayout();
}
...
}
4.3.3 [RootActivityContainer.java] resumeFocusedStacksTopActivities()
說明:獲取棧頂的Activity,恢復它
源碼:
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(),參考[4.3.4]
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
}
4.3.4 [ActivityStackSupervisor.java] startSpecificActivityLocked()
說明:發佈消息以啓動進程,以避免在ATM鎖保持的情況下調用AMS時可能出現死鎖,最終調用到ATM的startProcess()
源碼:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
...
//發佈消息以啓動進程,以避免在ATM鎖保持的情況下調用AMS時可能出現死鎖
//最終調用到AMS的startProcess(),參考[4.3.5]
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
...
}
4.3.5 [ActivityManagerService.java] startProcess()
說明:一路調用Process start(),最終到ZygoteProcess的attemptUsapSendArgsAndGetResult(),用來fork一個新的Launcher的進程
源碼:
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType, ComponentName hostingName) {
..
//同步操作,避免死鎖
synchronized (ActivityManagerService.this) {
//調用startProcessLocked,然後到 Process的start,最終到ZygoteProcess的attemptUsapSendArgsAndGetResult()
//用來fork一個新的Launcher的進程,參考[4.3.6]
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */, false /* isolated */,
true /* keepIfLarge */);
}
...
}
調用棧如下:
4.3.6 [ZygoteProcess.java] attemptZygoteSendArgsAndGetResult()
說明:通過Socket連接Zygote進程,把之前組裝的msg發給Zygote,其中processClass ="android.app.ActivityThread",通過Zygote進程來Fork出一個新的進程,並執行 "android.app.ActivityThread"的main方法
源碼:
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
//傳入的zygoteState爲openZygoteSocketIfNeeded(),裏面會通過abi來檢查是第一個zygote還是第二個
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
zygoteWriter.write(msgStr); //把應用進程的一些參數寫給前面連接的zygote進程,包括前面的processClass ="android.app.ActivityThread"
zygoteWriter.flush(); //進入Zygote進程,處於阻塞狀態, 參考[4.4]
//從socket中得到zygote創建的應用pid,賦值給 ProcessStartResult的對象
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}
4.4 第二階段Zygote fork一個Launcher進程的階段
說明:Zygote的啓動過程我們前面有詳細講到過。SystemServer的AMS服務向啓動Home Activity發起一個fork請求,Zygote進程通過Linux的fork函數,孵化出一個新的進程。
由於Zygote進程在啓動時會創建Java虛擬機,因此通過fork而創建的Launcher程序進程可以在內部獲取一個Java虛擬機的實例拷貝。fork採用copy-on-write機制,有些類如果不做改變,甚至都不用複製,子進程可以和父進程共享這部分數據,從而省去不少內存的佔用。
fork過程,參考下圖:
Zygote的調用棧如下:
4.4.1 [ZygoteInit.java] main()
說明:Zygote先fork出SystemServer進程,接着進入循環等待,用來接收Socket發來的消息,用來fork出其他應用進程,比如Launcher
源碼:
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()來進行進程的處理,參考[4.4.2]
caller = zygoteServer.runSelectLoop(abiList);
...
if (caller != null) {
caller.run(); //執行返回的Runnable對象,進入子進程
}
}
4.4.2 [ZygoteConnection.java] processOneCommand()
說明:通過forkAndSpecialize()來fork出Launcher的子進程,並執行handleChildProc,進入子進程的處理
源碼:
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
...
//參考[4.4.3]
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
//in parent
...
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
}
4.4.3 [ZygoteConnection.java] handleChildProc()
說明:進行子進程的操作,最終獲得需要執行的ActivityThread的main()
源碼:
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 */);
}
}
}
zygoteInit 進行一些環境的初始化、啓動Binder進程等操作:
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
RuntimeInit.commonInit(); //初始化運行環境
ZygoteInit.nativeZygoteInit(); //啓動Binder線程池
//調用程序入口函數
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
把之前傳來的"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);
}
}
}
4.5 第三個階段,Launcher在自己的進程中進行onCreate等後面的動作
從[4.4]可以看到,Zygote fork出了Launcher的進程,並把接下來的Launcher啓動任務交給了ActivityThread來進行,接下來我們就從ActivityThread main()來分析Launcher的創建過程。
調用棧如下:
4.5.1 [ActivityThread.java] main()
說明:主線程處理, 創建ActivityThread對象,調用attach進行處理,最終進入Looper循環
源碼:
public static void main(String[] args) {
// 安裝選擇性的系統調用攔截
AndroidOs.install();
...
//主線程處理
Looper.prepareMainLooper();
...
//之前SystemServer調用attach傳入的是true,這裏到應用進程傳入false就行
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
...
//一直循環,如果退出,說明程序關閉
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
調用ActivityThread的attach進行處理
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//應用進程啓動,走該流程
...
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//獲取AMS的本地代理類
final IActivityManager mgr = ActivityManager.getService();
try {
//通過Binder調用AMS的attachApplication方法,參考[4.5.2]
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
//通過system_server啓動ActivityThread對象
...
}
// 爲 ViewRootImpl 設置配置更新回調,
當系統資源配置(如:系統字體)發生變化時,通知系統配置發生變化
ViewRootImpl.ConfigChangedCallback configChangedCallback
= (Configuration globalConfig) -> {
synchronized (mResourcesManager) {
...
}
};
ViewRootImpl.addConfigCallback(configChangedCallback);
}
4.5.2 [ActivityManagerService.java] attachApplication()
說明:清除一些無用的記錄,最終調用ActivityStackSupervisor.java的 realStartActivityLocked(),進行Activity的啓動
源碼:
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);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
//如果當前的Application記錄仍然依附到之前的進程中,則清理掉
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}·
//mProcessesReady這個變量在AMS的 systemReady 中被賦值爲true,
//所以這裏的normalMode也爲true
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
...
//上面說到,這裏爲true,進入StackSupervisor的attachApplication方法
//去真正啓動Activity
if (normalMode) {
...
//調用ATM的attachApplication(),最終層層調用到ActivityStackSupervisor.java的 realStartActivityLocked()
//參考[4.5.3]
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
...
}
...
return true;
}
4.5.3 [ActivityStackSupervisor.java] realStartActivityLocked()
說明:真正準備去啓動Activity,通過clientTransaction.addCallback把LaunchActivityItem的obtain作爲回調參數加進去,再調用
ClientLifecycleManager.scheduleTransaction()得到
LaunchActivityItem的execute()方法進行最終的執行
參考上面的第三階段的調用棧流程
調用棧如下:
源碼:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// 直到所有的 onPause() 執行結束纔會去啓動新的 activity
if (!mRootActivityContainer.allPausedActivitiesComplete()) {
...
return false;
}
try {
// Create activity launch transaction.
// 添加 LaunchActivityItem
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
//LaunchActivityItem.obtain(new Intent(r.intent)作爲回調參數
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;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
// 重點關注:調用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法
//參考[4.5.4]
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
} catch (RemoteException e) {
if (r.launchFailed) {
// 第二次啓動失敗,finish activity
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash", false);
return false;
}
// 第一次失敗,重啓進程並重試
r.launchFailed = true;
proc.removeActivity(r);
throw e;
}
} finally {
endDeferResume();
}
...
return true;
}
4.5.4 [TransactionExecutor.java] execute()
說明:執行之前realStartActivityLocked()中的
clientTransaction.addCallback
源碼:
[TransactionExecutor.java]
public void execute(ClientTransaction transaction) {
...
// 執行 callBack,參考上面的調用棧,執行回調方法,
//最終調用到ActivityThread的handleLaunchActivity()參考[4.5.5]
executeCallbacks(transaction);
// 執行生命週期狀態
executeLifecycleState(transaction);
mPendingActions.clear();
}
4.5.5 [ActivityThread.java] handleLaunchActivity()
說明:主要乾了兩件事,第一件:初始化WindowManagerGlobal;第二件:調用performLaunchActivity方法
源碼:
[ActivityThread.java]
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
//初始化WindowManagerGlobal
WindowManagerGlobal.initialize();
...
//調用performLaunchActivity,來處理Activity,參考[4.5.6]
final Activity a = performLaunchActivity(r, customIntent);
..
return a;
}
4.5.6 [ActivityThread.java] performLaunchActivity()
說明:獲取ComponentName、Context,反射創建Activity,設置Activity的一些內容,比如主題等; 最終調用callActivityOnCreate()來執行Activity的onCreate()方法
源碼:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 獲取 ComponentName
ComponentName component = r.intent.getComponent();
...
// 獲取 Context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 反射創建 Activity
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
...
}
try {
// 獲取 Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
...
//Activity的一些處理
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, r.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
...
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
// 設置主題
activity.setTheme(theme);
}
activity.mCalled = false;
// 執行 onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
r.activity = activity;
}
//當前狀態爲ON_CREATE
r.setState(ON_CREATE);
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
return activity;
}
callActivityOnCreate先執行activity onCreate的預處理,再去調用Activity的onCreate,最終完成Create創建後的內容處理
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);
}
...
}
至此,看到了我們最熟悉的Activity的onCreate(),Launcher的啓動完成,Launcher被真正創建起來。
5.總結
看到onCreate()後,進入到我們最熟悉的Activity的入口,Launcher的啓動告一段落。整個Android的啓動流程,我們也完整的分析完成。
Launcher的啓動經過了三個階段:
第一個階段:SystemServer完成啓動Launcher Activity的調用
第二個階段:Zygote()進行Launcher進程的Fork操作
第三個階段:進入ActivityThread的main(),完成最終Launcher的onCreate操作
下一節會來分析一下Android的進程創建過程以及Zygote的fork流程。
微信公衆號:IngresGe