面試必備:Android Activity啟動流程源碼分析


最近大致分析了一把 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

這里我們差不多能猜到啟動邏輯:

  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 這種初始化一個普通進程的情況。

這個方法最后調用了 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】閱讀下載.

最后送給大家一句話:行動是老子、知識是兒子、創造是孫子。祝願大家能找到各自的方法,實現人生的持續突破。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM