Android Activity啓動流程源碼分析

最近大體分析了一把 Activity 啓動的流程,趁着今晚剛🏊完精神狀態好,把以前記錄的寫成文章。java

開門見山,咱們直接點進去看 Activity 的 startActivity , 最終,咱們都會走到 startActivityForResult 這個方法,咱們能夠發現關鍵的代碼:web

Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);
複製代碼

咱們會發現 Activity 啓動其實都通過了一箇中轉站叫作 Instrumentation, 查看InstrumentationexecStartActivity 方法:微信

/// 刪除了咱們不關心的部分
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。app

全局搜索 extends IActivityManager 咱們能夠發現進行通訊的就是 ActivityManagerService , 查看 startActivity 最終能夠走到 ActivityStartstartActivityMayWait 方法。咱們抽取它的關鍵代碼:socket

這部分咱們能夠看到根據 intent 解析除了須要的信息,並根據信息去獲取了跳轉 Activity 的系統權限。oop

這一部分代碼,則對 intent 進行了處理和判斷,咱們基本能夠省略這部分非關鍵邏輯this

最終咱們會走到 startActivityLocked 方法,並走到 startActivityspa

這裏咱們會看到不少對於不一樣的 ActivityManager 的 狀態進行邏輯判斷和處理,這裏不影響咱們的關鍵流程,咱們能夠繼續往下分析, 分析 doPendingActivityLaunchesLocked 方法線程

startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
                        null, null /*outRecords*/);
複製代碼

最終仍是會走到另外一個重載的 startActivity :3d

mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
複製代碼

查看 startActivityUnchecked : 這裏代碼邏輯比較長,咱們查看 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked 方法

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

這邊咱們查看須要 restart 這個 Activity 的簡單狀況,會調用 ActivityStackSupervisorstartSpecificActivityLocked 方法

這裏咱們找到了邏輯的關鍵:若是 app的線程和進程都存在,咱們會執行 realStartActivityLocked 方法。不然,會繼續進行 IPC 通知 ActivityManagerService 去執行 startProcessLocked

這裏咱們差很少能猜到啓動邏輯:

  1. 若是啓動的是咱們本身 app 進程的 Activity, 那麼直接去啓動就行了
  2. 若是咱們啓動的 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 後的幾個步驟

  1. attach Activity, 目測會有初始化 window 的流程
  2. 設置 theme
  3. Activity 的 onCreate 流程
  4. Activity 若是已經銷燬,會去執行 onRestoreInstance ,咱們能夠在這裏作數據恢復的操做
  5. Activity 在 onCreate 完成後的一些操做

到這裏,咱們的 Activity 就啓動成功了

啓動新的進程

下面來分析咱們的第二種狀況,咱們能夠跟蹤到 ActivityManagerService 的 `startProcessLocked 方法, 這個方法最終會走到本身的重載方法:

若是咱們啓動的是一個 webview service, 則會走到 startWebView ,這裏咱們不考慮,因此咱們分析的是 Process.start 這種初始化一個普通進程的狀況。

這個方法最後調用了 ZygoteProcessstart 方法

這裏咱們也能夠大體分析出來,這裏就是在經過 socket 通訊請求 Zygote 進程 fork 一個子進程,做爲新的 APP 進程,具體流程本篇文章暫時不作深究。

最終咱們會啓動 ActivityThreadmain 方法,繼續走到 attach 方法

這裏咱們能看到啓動主線程的 Looper, 建立系統 Context 等工做,最終咱們走到 ApplicationThreadbindApplication , 代碼這裏就不貼了,這裏負責了 Application 在初始化的時候的各類工做。包括 LoadedAPKmakeApplication 過程。

if (normalMode) {
	try {
		if (mStackSupervisor.attachApplicationLocked(app)) {
			didSomething = true;
		}
	} catch (Exception e) {
		Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
		badApp = true;
	}
}
複製代碼

這裏會發現,正常模式下,咱們走到了 ActivityStackSupervisorattachApplicationLocked 方法,後面就又會和第一部分介紹的同樣,走到 realStartActivityLocked 方法,去建立並執行 Activity 的生命週期。

總結

到這裏,Activity 的啓動流程就大體梳理出來了。基本就是,Instrumentation 負責 Activity 的建立和中轉, ActivityStackSupervisor 負責 Activity的 棧管理。Activity 都經過了 ActviityServerManager 來進行管理。

大概的關係以下圖所示:

後續

這裏我只是對Activity的啓動流程作了一個簡單的梳理。咱們會發現每一個模塊和細節都有幾百幾百行的代碼。很是的複雜。下面的內容有興趣你們也能夠細細探究。

  • 存在的 Activity 是怎麼管理的,怎麼走 onResume 去恢復的
  • Activity 不一樣的 launch mode是怎麼處理的
  • zygote fork 新的app進程的細節
  • LoadedApk 是怎麼加載 apk 的內容的
  • Activity 初始化完成後,內部是 window 又是怎麼初始化而且渲染上 UI 內容的
相關文章
相關標籤/搜索