最近大致分析了一把 Activity 啟動的流程,趁著今天精神狀態好,把之前記錄的寫成文章,
開門見山,我們直接點進去看 Activity 的 startActivity , 最終,我們都會走到 startActivityForResult 這個方法,我們可以發現關鍵的代碼:
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);
我們會發現 Activity 啟動其實都經過了一個中轉站叫做 Instrumentation, 查看Instrumentation 的 execStartActivity 方法:
/// 洗掉了我們不關心的部分
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
我們會發現這里通過 ActivityManager.getService 在進行通信,進去查看,我們發現這個 service 其實是一個 IActivityManager.aidl, 說明這里我們進行了一次 Android 的 IPC,
全域搜索 extends IActivityManager 我們可以發現進行通信的就是 ActivityManagerService , 查看 startActivity 最終可以走到 ActivityStart 的 startActivityMayWait 方法,我們抽取它的關鍵代碼:

這部分我們可以看到根據 intent 決議除了需要的資訊,并根據資訊去獲取了跳轉 Activity 的系統權限,

這一部分代碼,則對 intent 進行了處理和判斷,我們基本可以省略這部分非關鍵邏輯
最終我們會走到 startActivityLocked 方法,并走到 startActivity

這里我們會看到很多對于不同的 ActivityManager 的 狀態進行邏輯判斷和處理,這里不影響我們的關鍵流程,我們可以繼續往下分析, 分析 doPendingActivityLaunchesLocked 方法
startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
null, null /*outRecords*/);
最侄訓是會走到另一個多載的 startActivity :
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
查看 startActivityUnchecked : 這里代碼邏輯比較長,我們查看 ActivityStackSupervisor的.resumeFocusedStackTopActivityLocked 方法

繼續查看 resumeTopActivityUncheckedLocked 方法, 跟蹤到 resumeTopActivityInnerLocked 方法:

這邊我們查看需要 restart 這個 Activity 的簡單情況,會呼叫 ActivityStackSupervisor 的 startSpecificActivityLocked 方法

這里我們找到了邏輯的關鍵:如果 app的執行緒和行程都存在,我們會執行 realStartActivityLocked 方法,否則,會繼續進行 IPC 通知 ActivityManagerService 去執行 startProcessLocked
這里我們差不多能猜到啟動邏輯:
- 如果啟動的是我們自己 app 行程的 Activity, 那么直接去啟動就好了
- 如果我們啟動的 Activity 所在的行程不存在,例如:我們把微信 kill 了,然后跳轉微信分享的 Activity,或者我們點擊launch 的微信圖示,那么,我么就會走創建新行程的邏輯
那么我們分別來跟蹤這2種情況:
啟動自己的Activity

我們可以找到這段代碼的關鍵邏輯,我們先分析下 app.thread 是什么,跟蹤進去會發現是一個 IApplicationThread, 可以發現這里又是一個 aidl, 最后我們可以找到 ApplicationThread ,
private class ApplicationThread extends IApplicationThread.Stub
這是 ActivityThread 的一個靜態內部類,ActivtyThread和啟動Activity 相關,那么這個類就應該是和 Application 啟動相關,

我們會發現最后其實發了一個message 到訊息佇列中,找到 H 這個 handler 的 handleMessage 方法
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
查看 handleLaunchActivity 方法
Activity a = performLaunchActivity(r, customIntent);
在performLaunchActivity方法中可以看到
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
這里,我們發現這里通過 Insteumentation new 了一個 Activity


通過以上代碼,我們還可以發現 new 出 Activity 后的幾個步驟
- attach Activity, 目測會有初始化 window 的流程
- 設定 theme
- Activity 的
onCreate流程 - Activity 如果已經銷毀,會去執行
onRestoreInstance,我們可以在這里做資料恢復的操作 - Activity 在
onCreate完成后的一些操作
到這里,我們的 Activity 就啟動成功了
啟動新的行程
下面來分析我們的第二種情況,我們可以跟蹤到 ActivityManagerService 的 `startProcessLocked 方法, 這個方法最侄訓走到自己的多載方法:

如果我們啟動的是一個 webview service, 則會走到 startWebView ,這里我們不考慮,所以我們分析的是 Process.start 這種初始化一個普通行程的情況,
這個方法最后呼叫了 ZygoteProcess 的 start 方法

這里我們也可以大致分析出來,這里就是在通過 socket 通信請求 Zygote 行程 fork 一個子行程,作為新的 APP 行程,具體流程本篇文章暫時不做深究,
最終我們會啟動 ActivityThread 的 main 方法,繼續走到 attach 方法
這里我們能看到啟動主執行緒的 Looper, 創建系統 Context 等作業,最終我們走到 ApplicationThread 的 bindApplication , 代碼這里就不貼了,這里負責了 Application 在初始化的時候的各種作業,包括 LoadedAPK 的 makeApplication 程序,
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
這里會發現,正常模式下,我們走到了 ActivityStackSupervisor 的 attachApplicationLocked 方法,后面就又會和第一部分介紹的一樣,走到 realStartActivityLocked 方法,去創建并執行 Activity 的生命周期,
總結
到這里,Activity 的啟動流程就大致梳理出來了,基本就是,Instrumentation 負責 Activity 的創建和中轉, ActivityStackSupervisor 負責 Activity的 堆疊管理,Activity 都通過了 ActviityServerManager 來進行管理,
大概的關系如下圖所示:

后續
這里我只是對Activity的啟動流程做了一個簡單的梳理,我們會發現每個模塊和細節都有幾百幾百行的代碼,完全吃透還得自己下功夫,看原始碼,盡管這個程序很痛苦,一遍看不懂就再來一遍,跟著博客思路看了不下十遍,努力總會有識訓的,
最近收集到一份阿里大神整理的內部資料,包含**【Android開發核心知識筆記+2020大廠最新面試題及決議+原始碼筆記】**,如果你是卡在缺少學習資源的瓶頸上,那么剛剛好我能幫到你,
朋友們如果有需要,可以我的【Github】閱讀下載.


最后送給大家一句話:行動是老子、知識是兒子、創造是孫子,祝愿大家能找到各自的方法,實作人生的持續突破,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/211941.html
標籤:其他
