Activity啟動流程

引言

Activity啟動流程很多文章都已經(jīng)說過了,這里說一下自己的理解。
Activity啟動流程分兩種:

  • 一種是啟動正在運行的app的Activity,即啟動子Activity。如無特殊聲明默認和啟動該activity的activity處于同一進程。如果有聲明在一個新的進程中,則處于兩個進程。
  • 一種是打開新的app,即為Launcher啟動新的Activity。

后邊啟動Activity的流程是一樣的,區(qū)別是前邊判斷進程是否存在的那部分。

Activity啟動的前提是已經(jīng)開機,各項進程和AMS等服務(wù)已經(jīng)初始化完成,在這里也提一下那些內(nèi)容。

Activity啟動之前的一些事情

  • init進程:init是所有l(wèi)inux程序的起點,是Zygote的父進程。解析init.rc孵化出Zygote進程。

  • Zygote進程:Zygote是所有Java進程的父進程,所有的App進程都是由Zygote進程fork生成的。

  • SystemServer進程:System Server是Zygote孵化的第一個進程。SystemServer負責啟動和管理整個Java framework,包含AMS,PMS等服務(wù)。

  • Launcher:Zygote進程孵化的第一個App進程是Launcher。

    1.init進程是什么?

    Android是基于linux系統(tǒng)的,手機開機之后,linux內(nèi)核進行加載。加載完成之后會啟動init進程。
    init進程會啟動ServiceManager,孵化一些守護進程,并解析init.rc孵化Zygote進程。

    2.Zygote進程是什么?

    所有的App進程都是由Zygote進程fork生成的,包括SystemServer進程。Zygote初始化后,會注冊一個等待接受消息的socket,OS層會采用socket進行IPC通信。

    3.為什么是Zygote來孵化進程,而不是新建進程呢?

    每個應(yīng)用程序都是運行在各自的Dalvik虛擬機中,應(yīng)用程序每次運行都要重新初始化和啟動虛擬機,這個過程會耗費很長時間。Zygote會把已經(jīng)運行的虛擬機的代碼和內(nèi)存信息共享,起到一個預加載資源和類的作用,從而縮短啟動時間。

Activity啟動階段

涉及到的概念

  • 進程:Android系統(tǒng)為每個APP分配至少一個進程
  • IPC:跨進程通信,Android中采用Binder機制。

涉及到的類

  • ActivityStack:Activity在AMS的棧管理,用來記錄已經(jīng)啟動的Activity的先后關(guān)系,狀態(tài)信息等。通過ActivityStack決定是否需要啟動新的進程。
  • ActivitySupervisor:管理 activity 任務(wù)棧
  • ActivityThread:ActivityThread 運行在UI線程(主線程),App的真正入口。
  • ApplicationThread:用來實現(xiàn)AMS和ActivityThread之間的交互。
  • ApplicationThreadProxy:ApplicationThread 在服務(wù)端的代理。AMS就是通過該代理與ActivityThread進行通信的。
  • IActivityManager:繼承與IInterface接口,抽象出跨進程通信需要實現(xiàn)的功能
  • AMN:運行在server端(SystemServer進程)。實現(xiàn)了Binder類,具體功能由子類AMS實現(xiàn)。
  • AMS:AMN的子類,負責管理四大組件和進程,包括生命周期和狀態(tài)切換。AMS因為要和ui交互,所以極其復雜,涉及window。
  • AMP:AMS的client端代理(app進程)。了解Binder知識可以比較容易理解server端的stub和client端的proxy。AMP和AMS通過Binder通信。
  • Instrumentation:儀表盤,負責調(diào)用Activity和Application生命周期。測試用到這個類比較多。

流程圖

這個圖來源自網(wǎng)上,之前也看過很多類似講流程的文章,但是大都是片段的。這個圖是目前看到的最全的,自己去畫一下也應(yīng)該不會比這個全了,所以在這里直接引用一下,可以去瀏覽器上放大看。

涉及到的進程

  • Launcher所在的進程
  • AMS所在的SystemServer進程
  • 要啟動的Activity所在的app進程

如果是啟動根Activity,就涉及上述三個進程。
如果是啟動子Activity,那么就只涉及AMS進程和app所在進程。

具體流程

  • Launcher:Launcher通知AMS要啟動activity。
    • startActivitySafely->startActivity->Instrumentation.execStartActivity()(AMP.startActivity)->AMS.startActivity
  • AMS:PMS的resoveIntent驗證要啟動activity是否匹配。
    • 如果匹配,通過ApplicationThread發(fā)消息給Launcher所在的主線程,暫停當前Activity(Launcher);
  • 暫停完,在該activity還不可見時,通知AMS,根據(jù)要啟動的Activity配置ActivityStack。然后判斷要啟動的Activity進程是否存在?
    • 存在:發(fā)送消息LAUNCH_ACTIVITY給需要啟動的Activity主線程,執(zhí)行handleLaunchActivity
    • 不存在:通過socket向zygote請求創(chuàng)建進程。進程啟動后,ActivityThread.attach
  • 判斷Application是否存在,若不存在,通過LoadApk.makeApplication創(chuàng)建一個。在主線程中通過thread.attach方法來關(guān)聯(lián)ApplicationThread。
  • 在通過ActivityStackSupervisor來獲取當前需要顯示的ActivityStack。
  • 繼續(xù)通過ApplicationThread來發(fā)送消息給主線程的Handler來啟動Activity(handleLaunchActivity)。
  • handleLauchActivity:調(diào)用了performLauchActivity,里邊Instrumentation生成了新的activity對象,繼續(xù)調(diào)用activity生命周期。

IPC過程:

雙方都是通過對方的代理對象來進行通信。
1.app和AMS通信:app通過本進程的AMP和AMS進行Binder通信
2.AMS和新app通信:通過ApplicationThreadProxy來通信,并不直接和ActivityThread通信

參考函數(shù)流程

Activity啟動流程(從Launcher開始):

第一階段: Launcher通知AMS要啟動新的Activity(在Launcher所在的進程執(zhí)行)

  • Launcher.startActivitySafely //首先Launcher發(fā)起啟動Activity的請求
  • Activity.startActivity
  • Activity.startActivityForResult
  • Instrumentation.execStartActivity //交由Instrumentation代為發(fā)起請求
  • ActivityManager.getService().startActivity //通過IActivityManagerSingleton.get()得到一個AMP代理對象
  • ActivityManagerProxy.startActivity //通過AMP代理通知AMS啟動activity

第二階段:AMS先校驗一下Activity的正確性,如果正確的話,會暫存一下Activity的信息。然后,AMS會通知Launcher程序pause Activity(在AMS所在進程執(zhí)行)

  • ActivityManagerService.startActivity
  • ActivityManagerService.startActivityAsUser
  • ActivityStackSupervisor.startActivityMayWait
  • ActivityStackSupervisor.startActivityLocked :檢查有沒有在AndroidManifest中注冊
  • ActivityStackSupervisor.startActivityUncheckedLocked
  • ActivityStack.startActivityLocked :判斷是否需要創(chuàng)建一個新的任務(wù)來啟動Activity。
  • ActivityStack.resumeTopActivityLocked :獲取棧頂?shù)腶ctivity,并通知Launcher應(yīng)該pause掉這個Activity以便啟動新的activity。
  • ActivityStack.startPausingLocked
  • ApplicationThreadProxy.schedulePauseActivity

第三階段: pause Launcher的Activity,并通知AMS已經(jīng)paused(在Launcher所在進程執(zhí)行)

  • ApplicationThread.schedulePauseActivity
  • ActivityThread.queueOrSendMessage
  • H.handleMessage
  • ActivityThread.handlePauseActivity
  • ActivityManagerProxy.activityPaused

第四階段:檢查activity所在進程是否存在,如果存在,就直接通知這個進程,在該進程中啟動Activity;不存在的話,會調(diào)用Process.start創(chuàng)建一個新進程(執(zhí)行在AMS進程)

  • ActivityManagerService.activityPaused
  • ActivityStack.activityPaused
  • ActivityStack.completePauseLocked
  • ActivityStack.resumeTopActivityLocked
  • ActivityStack.startSpecificActivityLocked
  • ActivityManagerService.startProcessLocked
  • Process.start //在這里創(chuàng)建了新進程,新的進程會導入ActivityThread類,并執(zhí)行它的main函數(shù)

第五階段: 創(chuàng)建ActivityThread實例,執(zhí)行一些初始化操作,并綁定Application。如果Application不存在,會調(diào)用LoadedApk.makeApplication創(chuàng)建一個新的Application對象。之后進入Loop循環(huán)。(執(zhí)行在新創(chuàng)建的app進程)

  • ActivityThread.main
  • ActivityThread.attach(false) //聲明不是系統(tǒng)進程
  • ActivityManagerProxy.attachApplication

第六階段:處理新的應(yīng)用進程發(fā)出的創(chuàng)建進程完成的通信請求,并通知新應(yīng)用程序進程啟動目標Activity組件(執(zhí)行在AMS進程)

  • ActivityManagerService.attachApplication //AMS綁定本地ApplicationThread對象,后續(xù)通過ApplicationThreadProxy來通信。
  • ActivityManagerService.attachApplicationLocked
  • ActivityStack.realStartActivityLocked //真正要啟動Activity了!
  • ApplicationThreadProxy.scheduleLaunchActivity //AMS通過ATP通知app進程啟動Activity

第七階段: 加載MainActivity類,調(diào)用onCreate聲明周期方法(執(zhí)行在新啟動的app進程)

  • ApplicationThread.scheduleLaunchActivity //ApplicationThread發(fā)消息給AT
  • ActivityThread.queueOrSendMessage
  • H.handleMessage //AT的Handler來處理接收到的LAUNCH_ACTIVITY的消息
  • ActivityThread.handleLaunchActivity
  • ActivityThread.performLaunchActivity
  • Instrumentation.newActivity //調(diào)用Instrumentation類來新建一個Activity對象
  • Instrumentation.callActivityOnCreate
  • MainActivity.onCreate
  • ActivityThread.handleResumeActivity
  • AMP.activityResumed
  • AMS.activityResumed(AMS進程)

參考文章

http://gityuan.com/2016/03/12/start-activity/
https://blog.csdn.net/luoshengyang/article/details/6689748

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 整個 startActivity 的流程分為3大部分,也涉及3個進程之間的交互: ActivityA --> Ac...
    倉頡空閱讀 1,392評論 0 0
  • 1 前言 日常開發(fā)過程中我們經(jīng)常調(diào)用startActivity(..)啟動新的Activity,那么系統(tǒng)是如何找到...
    9283856ddec1閱讀 1,150評論 0 1
  • Zygote是什么?有什么作用? Android系統(tǒng)底層基于Linux Kernel, 當Kernel啟動過程會創(chuàng)...
    Mr槑閱讀 2,918評論 4 18
  • 前端時間看了一下framework的源碼,把activity啟動流程系統(tǒng)的學習了一下,涉及的源代碼較多,本文是基于...
    雷濤賽文閱讀 1,414評論 1 1
  • 學習要抓住重點,提問題是一個不錯的方法 一、知識儲備型問題 1. 什么是進程?如何創(chuàng)建一個進程?(Android ...
    Marker_Sky閱讀 528評論 0 2

友情鏈接更多精彩內(nèi)容