Activity的啟動過程


app啟動的過程有兩種情況,第一種是從桌面launcher上點擊相應的應用圖標,第二種是在activity中通過調用startActivity來啟動一個新的activity。
我們創建一個新的項目,默認的根activity都是MainActivity,而所有的activity都是保存在堆棧中的,我們啟動一個新的activity就會放在上一個activity上面,而我們從桌面點擊應用圖標的時候,由於launcher本身也是一個應用,當我們點擊圖標的時候,系統就會調用startActivitySately(),一般情況下,我們所啟動的activity的相關信息都會保存在intent中,比如action,category等等。我們在安裝這個應用的時候,系統也會啟動一個PackaManagerService的管理服務,這個管理服務會對AndroidManifest.xml文件進行解析,從而得到應用程序中的相關信息,比如service,activity,Broadcast等等,然后獲得相關組件的信息。當我們點擊應用圖標的時候,就會調用startActivitySately()方法,而這個方法內部則是調用startActivty(),而startActivity()方法最終還是會調用startActivityForResult()這個方法。而在startActivityForResult()這個方法。因為startActivityForResult()方法是有返回結果的,所以系統就直接給一個-1,就表示不需要結果返回了。而startActivityForResult()這個方法實際是通過Instrumentation類中的execStartActivity()方法來啟動activity,Instrumentation這個類主要作用就是監控程序和系統之間的交互。而在這個execStartActivity()方法中會獲取ActivityManagerService的代理對象,通過這個代理對象進行啟動activity。啟動會就會調用一個checkStartActivityResult()方法,如果說沒有在配置清單中配置有這個組件,就會在這個方法中拋出異常了。當然最后是調用的是Application.scheduleLaunchActivity()進行啟動activity,而這個方法中通過獲取得到一個ActivityClientRecord對象,而這個ActivityClientRecord通過handler來進行消息的發送,系統內部會將每一個activity組件使用ActivityClientRecord對象來進行描述,而ActivityClientRecord對象中保存有一個LoaderApk對象,通過這個對象調用handleLaunchActivity來啟動activity組件,而頁面的生命周期方法也就是在這個方法中進行調用。
 
任玉剛大佬談:https://blog.csdn.net/u010648159/article/details/81103092

Activity的啟動過程,我們可以從Context的startActivity說起,其實現是ContextImpl的startActivity,然后內部會通過Instrumentation來嘗試啟動Activity,這是一個跨進程過程,它會調用ams的startActivity方法,當ams校驗完activity的合法性后,會通過ApplicationThread回調到我們的進程,這也是一次跨進程過程,而applicationThread就是一個binder,回調邏輯是在binder線程池中完成的,所以需要通過Handler H將其切換到ui線程,第一個消息是LAUNCH_ACTIVITY,它對應handleLaunchActivity,在這個方法里完成了Activity的創建和啟動,接着,在activity的onResume中,activity的內容將開始渲染到window上,然后開始繪制直到我們看見。

3分鍾看懂Activity啟動流程

 

在上圖中,ActivityManagerService和ActivityStack位於同一個進程中,而ApplicationThread和ActivityThread位於另一個進程中。其中,ActivityManagerService是負責管理Activity的生命周期的,ActivityManagerService還借助ActivityStack是來把所有的Activity按照后進先出的順序放在一個堆棧中;

    對於每一個應用程序來說,都有一個ActivityThread來表示應用程序的主進程,而每一個ActivityThread都包含有一個ApplicationThread實例,它是一個Binder對象,負責和其它進程進行通信。

下面簡要介紹一下啟動的過程:

        Step 1. 無論是通過Launcher來啟動Activity,還是通過Activity內部調用startActivity接口來啟動新的Activity,都通過Binder進程間通信進入到ActivityManagerService進程中,並且調用ActivityManagerService.startActivity接口; 

        Step 2. ActivityManagerService調用ActivityStack.startActivityMayWait來做准備要啟動的Activity的相關信息;

        Step 3. ActivityStack通知ApplicationThread要進行Activity啟動調度了,這里的ApplicationThread代表的是調用ActivityManagerService.startActivity接口的進程,對於通過點擊應用程序圖標的情景來說,這個進程就是Launcher了,而對於通過在Activity內部調用startActivity的情景來說,這個進程就是這個Activity所在的進程了;

        Step 4. ApplicationThread不執行真正的啟動操作,它通過調用ActivityManagerService.activityPaused接口進入到ActivityManagerService進程中,看看是否需要創建新的進程來啟動Activity;

        Step 5. 對於通過點擊應用程序圖標來啟動Activity的情景來說,ActivityManagerService在這一步中,會調用startProcessLocked來創建一個新的進程,而對於通過在Activity內部調用startActivity來啟動新的Activity來說,這一步是不需要執行的,因為新的Activity就在原來的Activity所在的進程中進行啟動;

        Step 6. ActivityManagerServic調用ApplicationThread.scheduleLaunchActivity接口,通知相應的進程執行啟動Activity的操作;

        Step 7. ApplicationThread把這個啟動Activity的操作轉發給ActivityThread,ActivityThread通過ClassLoader導入相應的Activity類,然后把它啟動起來。

 

 
Activity到AMS一次IPC調用
AMS到Activity的一次IPC過程
 
雙向Binder的建立
以上參考 https://www.jianshu.com/p/e0a6717bc75e


免責聲明!

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



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