ActivityManagerService流程

Activity啟動流程

目的:

  • 理清activity的生命周期管理與AMS之間的關系

一、理清activity的生命周期管理與AMS之間的關系

1、Launcher通知AMS啟動某個activity:

Launcher中:應用程序中開啟一個activity通過startActivitySafely()---->startActivity(),如果是程序內部啟動那么直接調用Activity中的startActivity(),被啟動的activity的參數包含在intent中,intent中的參數來自于.xml
文件,--->startActivityForResult()----> mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options),其中Instrumentation是用來監控應用程序與系統之間的交互,其中mMainThread是ActivityThread類的實例,.getApplicationThread()用于獲取內部的ApplicationThread的Binder對象(此處有疑問??);----->ActivityManagerNative.getDefault()
.startActivity(), .getDefault()通過ServerManager獲取AMS的代理對象"activity",代碼如下:

//ActivityManagerNative.java
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity"); //獲取代理對象
            if (false) {
               Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
           return am;
        }
};

接著調用他的方法startActivity()通知AMS啟動相應的Activity,這里已經是binder通訊了。

startActivitySafely()    <-----------------Launcher中,如果是在Launcher中點擊,從這一步開始
        |
startActivity()          <-----------------Activity中,如果是程序中調用,從這一步開始
    |
startActivityForResult() <-----------------Activity中
    |
mInstrumentation.execStartActivity()  <----------Instrumentation中
    |
ActivityManagerNative.getDefault().startActivity()<----------AMS的proxy
    |
    ...binder...    Launcher--->AMS: Launcher請求啟動activity
    |
startActivity()    ---------->通知AMS的Stub中startActivity(),即ActivityManagerService.java中的

至此Launcher中暫時結束!即Launcher進程會------>請求AMS啟動一個activity,具體是哪一個activity,看intent

2、AMS保存將要啟動的mainactivity,并且AMS處理Launcher向AMS發送的binder消息:START_ACTIVITY_TRANSACTION

startActivity()                     ------->AMS   
    |
startActivityAsUser()               ------->AMS
    |
mStackSupervisor.startActivityMayWait() ------->ActivityStackSupervisor.java 
    |
startActivityLocked()           ------->ActivityStackSupervisor.java      
    |
startActivityUncheckedLocked()
    |
resumeTopActivitiesLocked(targetStack, null, options)  ----->ActivityStack.java
    |
startPausingLocked()                ----->ActivityStack.java
    |
prev.app.thread.schedulePauseActivity() ----->ActivityStack.java   Proxy
    |
    ...binder...    AMS--->Launcher: AMS請求Launcher Pause
    |
schedulePauseActivity()         ------>ActivityThread.java   Stub  

//ActivityThread.java
public final void schedulePauseActivity(IBinder token, boolean finished,
          boolean userLeaving, int configChanges, boolean dontReport) {
     sendMessage(
             finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
             token,
             (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
             configChanges);
}
    1. mStackSupervisor.startActivityMayWait()中還會用binder和PMS通訊,解析intent中的界面內容,以便顯示
    1. mStackSupervisor是ActivityStackSupervisor的成員變量,用于描述Activity組件堆棧(疑問???)
    1. startPausingLocked()中又會涉及到一個binder通訊,這個是AMS向Launcher組件所在的應用程序進程發送通訊SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:需要Pause掉Launcher了
      至此AMS暫時結束,即AMS向Launcher組件所在的應用程序進程發送了SCHEDULE_PAUSE_ACTIVITY_TRANSACTION進程間通訊請求,請求內容是告訴Launcher組件Pause吧。當然其中會有一些列的異步超時處理。

3、Launcher收到Pause請求后的動作,并回復AMS(通過AMS的proxy)

schedulePauseActivity()         ------>ActivityThread.java   Stub  
    |
sendMessage()               ------>ActivityThread.java  果然這里是消息處理機制實現
    |
handleMessage(Message msg)      ------>ActivityThread.java  
    |   
handlePauseActivity()
    |
performPauseActivity(token, finished, r.isPreHoneycomb());   ------>ActivityThread.java  
ActivityManagerNative.getDefault().activityPaused(token)     ------>ActivityThread.java  AMS proxy
    |
    ...binder...    Launcher--->AMS : Launcher告知AMS,Launcher已經Pause
    |
activityPaused(token)           ------>AMS Stub
    1. activityPaused()獲取AMS的proxy,用于回復AMS:告訴AMS,Launcher已經進入Pause狀態了;AMS你可以繼續啟動Activity了。
    1. performPauseActivity()--->mInstrumentation.callActivityOnPause(r.activity)--->activity.performPause() ---> onPause() 這應該就是與APP繼承的 onPause()一致的。

疑問:

  • 至此Launcher已經Paused了,并通過binder進程間通訊發送了ACTIVITY_PAUSED_TRANSACTION告知AMS。

4、AMS中處理Launcher發來的Paused通訊請求,并做相應處理

activityPaused(token)           ------>AMS Stub
    |
activityPausedLocked()          ------>ActivityStack.java
    |
completePauseLocked(true)
    |
finishCurrentActivityLocked()
    |
resumeTopActivityLocked()
    |
resumeTopActivityInnerLocked()
    |
startSpecificActivityLocked()       ------->ActivityStackSupervisor.java
    |
startProcessLocked()            ------->AMS
    |
startProcessLocked()            ------->重載的函數,  AMS (如果進程不在的話)
//AMS  startProcessLocked()
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
        app.processName, uid, uid, gids, debugFlags, mountExternal,
        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
        app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
    |
try {
    return startViaZygote(processClass, niceName, uid, gid, gids,
        debugFlags, mountExternal, targetSdkVersion, seInfo,
        abi, instructionSet, appDataDir, zygoteArgs);
} 
    |
zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)
    |
通知zygote孵化出新的虛擬機應用程序,并返回PID給AMS,新的應用程序啟動起來之后就會進入ActivityThread的main方法中。

至此,AMS就調用Process類創建了一個新的應用程序。并且,該進程的入口函數為main函數,接下來就是新的應用程序進程的工作了。

5、新的應用程序啟動之后,會向AMS發送一個啟動完成的進程間通訊。

main()                  ------->ActivityThread.java
    |
Looper.prepareMainLooper()  ------->創建消息循環隊列,是當前應用進程進入消息循環隊列中
ActivityThread thread = new ActivityThread()          創建一個ActivityThread對象  
attach(boolean system)      ------->ActivityThread.java
    |
final IActivityManager mgr = ActivityManagerNative.getDefault();//獲取AMS的proxy
mgr.attachApplication(mAppThread)       ----->AMS proxy,調用IActivityManager的接口通訊函數
    |
    ...binder...    ActivityThread--->AMS: APP進程告知AMS啟動進程完成
    |
attachApplication(IApplicationThread thread)    ----->AMS Stub
    |
Looper.loop()   

至此,新的應用程序進程通過調用,thread.attach(false)調用attach()函數來向AMS的proxy發送一個進程間通訊回復ATTACH_APPLICATION_TRANSACTION:告訴AMS新的應用程序已經啟動完成。

6、 AMS將2步中保存的MainActivity信息,發送給第4步中創建的新應用程序,,以便它可以將MainActivity啟動起來

attachApplication(IApplicationThread thread)    ----->AMS Stub
    |
attachApplicationLocked(IApplicationThread thread, int pid) ----->AMS 
    |
attachApplicationLocked(ProcessRecord app)  ----->ActivityStackSupervisor.java  重載
    |
realStartActivityLocked(hr, app, true, true)    ----->ActivityStackSupervisor.java      
    |
app.thread.scheduleLaunchActivity()     ----->ActivityThread proxy
    |
    ...binder...    AMS--->ActivityThread: AMS將MainActivity信息發送新進程
    |
scheduleLaunchActivity()            ----->ActivityThread Stub

至此,AMS向ActivityThread發送進程間通訊SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION

7、應用程序中執行最后工作

scheduleLaunchActivity()            ----->ActivityThread Stub
    |
sendMessage(H.LAUNCH_ACTIVITY, r)       
    |
handleMessage(Message msg)
    |
handleLaunchActivity(r, null)
    |
Activity a = performLaunchActivity(r, customIntent)
    |
mInstrumentation.callActivityOnCreate(activity, r.state)  ------->Instrumentation.java
    |
activity.performCreate(icicle)
    |
onCreate(icicle)        ------>Activity.java
    |
protected void onCreate(@Nullable Bundle savedInstanceState) 

APP中繼承的OnCreate()就被調用起來了,最后一步將Activity對象activity啟動起來了

注意:

1、mainActivity組件是由Launcher組件啟動的,Launcher組件又是通過AMS來啟動mainActivity的,因此會涉及到三個進程之間的binder通訊
2、AMS啟動是和PMS一樣,都在systemServer進程中啟動起來的,startBootstrapServices()函數中。
3、還得理清楚ActivityManagerService.java,ActivityManagerNative.java,IActivityManager.java之間的關系

  1. ActivityManagerService.java毋庸置疑肯定是Activity棧管理實現
  2. ActivityManagerNative.java根據代碼看,應該是BnXXXX和BpXXXX,也就是binder本地和代理,ActivityManagerService里面才是真正的物理實現。所有的通訊都是通過ActivityManagerNative處理的
  3. IActivityManager.java當然是接口類,ActivityManagerNative實現IActivityManager。

總結,問題:

    1. 目前只看到onCreate() 被調用的地方,其他的生命周期onRestart(),onStart(), onResume() ,onPause() ,onStop() ,onDestroy() 是怎么被AMS調用轉換的???
      解:都在ActivityThread(UI主線程)管理的,當發生生命周期變換時,最終都會call到Activity.java中去,而這個文件正是APP中繼承的Activity。
      應用進程啟動時會先創建Application對象,并執行Application對象的生命周期方法,然后才啟動應用的組件。
      ActivityThread ---> performPauseActivity() ---> callActivityOnPause()--->performPause()--->onPause()
      ActivityThread ---> performResumeActivity() --> performResume()--->onResume()
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        // Initialize before creating the activity
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);   // launch之后緊接著調用ResumeActivity

            if (!r.activity.mFinished && r.startsNotResumed) {
                performPauseActivityIfNeeded(r, reason);
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        }
    }

...

    1. ActivityStack堆棧組件???
      解:mStackSupervisor是ActivityStackSupervisor的成員變量,用于描述Activity組件堆棧
      在startActivityLocked方法里,對傳過來的參數做一些校驗,然后創建ActivityRecord對象,再調用startActivityUncheckedLocked方法啟動Activity。
      startActivityUncheckedLocked方法負責調度ActivityRecord和Task,理解該方法是理解Actvity啟動模式的關鍵。
    1. Activity與Window對應關系?
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容