Activity啟動流程筆記
一直遇到這個問題,而且提示與生命週期不同,很是疑惑。於是網上搜羅,並翻看《Android開發藝術探索》,發現多是程式碼,長篇大論。好奇心所致,一路ctrl+B,看看能收穫些什麼。
Activity的啟動流程,涉及應用程序端和系統服務端兩部分,因此,為跨程序通訊。既然是跨程序,那就離不開Android的Binder機制。
Binder機制,為C/S模式,是單向的。而應用程序端與系統服務端的通訊是雙向的,互為Client/Server。所以,需要兩個Binder。ActivityManagerNative和ApplicationThreadNative就是這兩個Binder。先說一下,這兩Binder及其子類。
ActivityManagerNative
ActivityManagerNative繼承自Binder,實現了IActivityManager介面(該介面定義了與Activity manager Service通訊的介面)。ActivityManagerNative還包含一個內部類ActivityManagerProxy。但ActivityManagerNative仍是一個抽象類。
ActivityManagerService
ActivityManagerService繼承於ActivityManagerNative,並實現了內部的抽象方法。該類物件位於系統程序中。
因此,ActivityManagerProxy
通過呼叫ActivityManagerProxy物件所提供的方法,完成應用程序端至系統服務端的通訊。
ApplicationThreadNative
ApplicationThreadNative繼承自Binder,實現了IApplicationThread介面(該介面定義了與Application通訊的介面)。ApplicationThreadNative也包含一個內部類ApplicationThreadProxy。ApplicationThreadNative
ApplicationThread
ApplicationThread繼承自ApplicationThreadNative,並實現了內部抽象方法。
ApplicationThread是ActivityThread的一個內部私有類。
ActivityThread是應用的主執行緒。
ActivityThread還存在一個內部私有類H,實為Handler,用於處理內部訊息。
通過呼叫ApplicationThreadProxy物件所提供的方法,完成系統服務端至應用程序端的通訊。
由於ApplicationThread和ActivityManagerService的存在,使得雙向通訊得以完成。
與生命週期的關係
Activity的啟動,涉及android framework,需要閱讀核心程式碼,且程式碼十分繁瑣。因此,對於其流程,也只能看一下順序,瞭解個大概的機制。
結合Activity的生命週期,整個流程大致分以下幾步:
(1)執行棧頂activity的onPause;
(2)檢視當前要啟動的目標activity所在程序是否被建立。若未建立則,則執行步驟(3);否則,跳至步驟(4);
(3)啟動activity所在程序;
(4)依次觸發activity的生命週期方法,onCreate,onStart,onResume;
(5)觸發原棧頂activity的onStop方法。
但,畢竟啟動過程,不僅僅是生命週期方法的呼叫。硬著頭皮,捋著程式碼走了一遍。才有了以下筆記。希望有助於記憶。
參考
整理過程中,參考了部分文章,也列在下面。
文中有部分描述還是模糊,仍需要檢視程式碼,才得以確認。
此外,對於android framework程式碼,若不想下載,可訪問網址
線上檢視。只需要輸入要查詢的類即可,很方便。
小結
先把小結寫在前面,時因為整個Go To Definition過程多少有些乏味和漫長。
這個過程中,會在ActivityThread(將要啟動的Activity),ActivityThread(當前處於棧頂的Activity)和ActivityManagerService間不斷的跳轉。因為前兩者是不同的程序,不能直接通訊,所以需要系統服務程序ActivityManagerService這個管理者出現,為兩者傳遞資訊。
系統核心程序zygote,也會參與到啟動過程中。當將要啟動的Activity所在的程序未被啟動時,zygote將建立該程序。
(1)呼叫startActivity時,當前程序會通過ActivityManagerProxy向AMS(ActivityManagerService)傳送資訊。通知其執行當前棧頂的Activity的onPause。
(2)AMS收到請求後,通過ApplicationThreadProxy向當前棧頂Activity的ActivityThread傳送資訊。
(3)當前棧頂Activity的ActivityThread接收到請求後,傳送message給H,H觸發該Activity的onPause。執行完畢後,當前棧頂Activity的ActivityThread,通過ActivityManagerProxy通知AMS(ActivityManagerService),操作完成。
(4)AMS收到請求後,檢視將要啟動的目標Activity所在程序是否已被啟動。若未啟動,則通知系統核心zygote建立程序,並將程序啟動類ActivityThread名稱作為引數,提供給zygote.
(5)zygote建立完程序後,觸發ActivityThread的Main方法,初始化程序。初始化結束後,ActivityThread通過ActivityManagerProxy通知AMS(ActivityManagerService)操作完畢。
(6)AMS收到請求後,通過ApplicationThreadProxy向目標ActivityThread(新建成的)傳送請求,要求其啟動目標Activity。
(7)目標ActivityThread收到請求後,傳送message給H,H依次觸發handleLaunchActivity操作,和handleResumeActivity操作。前者執行目標Activity的onCreate和onStart,後者執行onResume。handleResumeActivity最後會再次通過ActivityManagerProxy通知AMS(ActivityManagerService),進行Idle操作。
(8)AMS接收請求後,會在空閒時通過ApplicationThreadProxyt通知原棧頂Activity的ActivityThread,對原棧頂Activity執行onPause操作。或在記憶體不足時,執行onSaveInstanceState操作。
整個流程小結完畢。
Go to Definition
下面是走流程時做的筆記。
(1)棧頂activity的onPause
啟動一個Activity,是從startActivity()方法開始的逐級呼叫。
startActivity
->startActivityForResult
->Instrumentation.execStartActivity
->ActivityManagerNative.getDefault().startActivity
Instrumentation是Activity的一個應用程序端的實際操作類。
當呼叫ActivityManagerNative.getDefault().startActivity時,根據Binder機制,實際是呼叫了ActivityManagerService物件的startActivity方法。操作從應用程序端,跳轉至系統服務端。
ActivityManagerService.startActivity
->startActivityAsUser
->StackSupervisor.startActivityMayWait
-> StackSupervisor.startActivityLocked
-> StackSupervisor.startActivityUncheckedLocked
-> ActivityStack.startActivityLocked
-> ActivityStackSupervisor.resumeTopActivitiesLocked
->ActivityStack.resumeTopActivityLocked
->ActivityStack.startPausingLocked
-> prev.app.thread.schedulePauseActivity
prev.app.thread為一個IApplicationThread物件,即ApplicationThreadProxy物件。
因此,此時操作又從系統服務端,跳轉至應用程序端。該程序為棧頂Activity所在的程序。繼續,
ApplicationThread.schedulePauseActivity
->ActivityThread.sendMessage (PAUSE_ACTIVITY_FINISHING)
->H.sendMessage
->H.handleMessage
->ActivityThread.handlePauseActivity
->ActivityThread.performPauseActivity
->mInstrumentation.callActivityOnPause
->activity.performPause
->ActivityManagerNative.getDefault().activityPaused
在應用程序中,ApplicationThread傳送PAUSE_ACTIVITY_FINISHING訊息至H,H處理後,觸發mInstrumentation,最終呼叫了activity.performPause方法。
至此,棧頂activity 在應用程序端的Pause處理結束。
(2)啟動目標Activity所在程序。
在上一階段的ActivityThread.handlePauseActivity方法中,處理完應用程序端的Pause處理後,還呼叫了ActivityManagerNative.getDefault().activityPaused,使得處理流程,再次從應用程序端,跳轉至系統服務端。
ActivityManagerService.activityPaused
->ActivityStack.activityPausedLocked
->ActivityStack.completePauseLocked
->ActivityStackSupervisor.resumeTopActivitiesLocked
->ActivityStack.resumeTopActivityLocked
->ActivityStack.resumeTopActivityInnerLocked
->ActivityStackSupervisor.startSpecificActivityLocked
->ActivityStackSupervisor.realStartActivityLocked
Or
->mService.startProcessLocked
其中,ActivityStackSupervisor.startSpecificActivityLocked方法,會判斷一下需要啟動的目標Activity所在應用程序是否已經啟動,若啟動的話,則直接呼叫ActivityStackSupervisor.realStartActivityLocked方法,觸發目標Activity的生命週期;否則,呼叫mServicestartProcessLocked方法,用於啟動應用程序。
而mService是什麼?一個ActivityManagerService物件。
因此,在目標Activity所在應用程序未被啟動的情況下,呼叫StartProcessLocked方法時,操作又從應用程序端,轉至系統服務端。
ActivityManagerService. startProcessLocked
->Process.start
-> Process.startViaZygote
->Process.zygoteSendArgsAndGetResult
Zygote是android系統中用於建立新程序的核心程序。每個程序都有一個啟動類。
程序的啟動類名“android.app.ActivityThread”被當做引數,在Process.start方法中設定,並傳入Process.startViaZygote中。
當新程序建立完畢後,會依照啟動類名反射至啟動類,並自動執行程序啟動類的main方法。即ActivityThread的main方法。
ActivityThread.main
->new ActivityThread
-> ActivityThread.attach
-> ActivityManagerNative.getDefault.attachApplication
再次跳轉至ActivityManagerService中。
ActivityManagerService.attachApplicationLocked
->ActivityStackSupervisor.attachApplicationLocked
->ActivityStackSupervisor.realStartActivityLocked
又見到realStartActivityLocked方法了。之前提過,該方法是用於啟動Activity的。因此,說明從當前位置開始,將進行目標activity的生命週期操作。程序啟動操作完畢。
(3)啟動Activity。
ActivityStackSupervisor.realStartActivityLocked
->app.thread.scheduleLaunchActivity
操作從系統服務端跳轉至應用程序端。
ActivityThread.scheduleLaunchActivity
->sendMessage(H.LAUNCH_ACTIVITY)
->H.handleMessage
->ActivityThread.handleLaunchActivity
->ActivityThread.performLaunchActivity
->mInstrumentation.callActivityOnCreate
->activity.performCreate
->activity.onCreate
->activity.performStart
->mInstrumentation.callActivityOnStart
-> activity.onStart
->ActivityThread.handleResumeActivity
->ActivityThread.performResumeActivity
->r.activity.performResume
->mInstrumentation.callActivityOnResume
->activity.onResume
->Looper.myQueue().addIdleHandler(new Idle)
從過程中可以看到,在處理LAUNCH_ACTIVITY訊息時,handler執行了ActivityThread.handleLaunchActivity方法。該方法依次執行了兩個方法,ActivityThread.performLaunchActivity和ActivityThread.handleResumeActivity。前者觸發了目標activity的onCreate方法,和onStart方法。而後者,則觸發了activity的onResume方法。
至此Activity完成顯示。但這並未結束。此前棧頂的activity還有操作未完成。
(4)執行棧頂Activity的onStop。
在處理目標activity onResume生命週期的handleResumeActivity方法中,結尾處,呼叫了Looper.myQueue().addIdleHandler(new Idler())。這個方法很不起眼,但卻觸發了空閒情況下的處理機制。
Idler繼承於MessageQueue.IdleHandler。用於線上程空閒時,執行某種操作。空閒時,其queueIdle方法將被觸發。
Idler.queueIdle
->ActivityManagerNative.getDefault().activityIdle
又是一個熟悉的身影~再次跳轉至系統服務端。
ActivityManagerService.activityIdle
->ActivityStack.stopActivityLocked()
->r.app.thread.scheduleStopActivity
再次跳轉至應用程序端,原置頂activity所在的程序。
ActivityThread.scheduleStopActivity
-> ActivityThread.sendMessage
->H.handleMessage
->ActivityThread.handleStopActivity
-> ActivityThread.performStopActivityInner
->ActivityThread.callCallActivityOnSaveInstanceState
or
->Activity.performStop
在ActivityThread.performStopActivityInner方法中,根據情況,會觸發兩個不同的操作。若記憶體不足,需要回收,則觸發ActivityThread.callCallActivityOnSaveInstanceState;而正常情況下,則會觸發Activity.performStop。
我們先來看一下正常情況。
Activity.performStop
->mInstrumentation.callActivityOnStop
->Activity.onStop
終於,onStop出現。 原棧頂activity的onStop完成。
再來看,記憶體不足的情況。
ActivityThread.callCallActivityOnSaveInstanceState
->mInstrumentation.callActivityOnSaveInstanceState
->Activity.performSaveInstanceState
->Activity.onSaveInstanceState
原棧頂activity的onSaveInstanceState方法完成。
至此,整個Activity的啟動完畢。