天天看點

android裡面的Activity體系結構(3)_ActivityRecord和Activity狀态變化分析說明

ActivityRecord是運作在system_server程序裡面的,Activity是運作在應用程序裡面的,雖然内部有個變量ActivityInfo info來代表Activity的所有資訊,但是狀态的變化不是和Activity完全一緻,Activity的狀态變化是由ActivityRecord狀态變化來影響并改變的

1.ActivityRecord 狀态

在ActivityRecord裡面有個内部變化ActivityState mState,每次狀态有變化的時候,都會調用setState方法來設定,其定義如下:

enum ActivityState {
        INITIALIZING,
        RESUMED,
        PAUSING,
        PAUSED,
        STOPPING,
        STOPPED,
        FINISHING,
        DESTROYING,
        DESTROYED,
        RESTARTING_PROCESS
    }
           
2.Activity 狀态

activity生命周期的幾個方法定義:

*     protected void onCreate(Bundle savedInstanceState);
 *
 *     protected void onStart();
 *
 *     protected void onRestart();
 *
 *     protected void onResume();
 *
 *     protected void onPause();
 *
 *     protected void onStop();
 *
 *     protected void onDestroy();
           
3.ActivityRecord 狀态變化

主要在ActivityStack類裡面,如下關鍵方法會設定不同狀态

// setState(PAUSING)
ActivityStack.startPausingLocked()

// setState(PAUSED)
ActivityStack.completePauseLocked()

// setVisibility(true)
ActivityStack.startActivityLocked

// 首先setState(STOPPING),然後發送消息STOP_TIMEOUT_MSG,調用ActivityRecord.activityStoppedLocked來設定setState(STOPPED)
ActivityStack.stopActivityLocked

//  setState(FINISHING)
ActivityStack.finishActivityLocked

// setState(DESTROYING),然後發送消息DESTROY_TIMEOUT_MSG,setState(DESTROYED)
ActivityStack.destroyActivityLocked

// setState(RESUMED)
ActivityStack.minimalResumeActivityLocked
           

注意,STOPPED狀态是通過調用ActivityRecord的activityStoppedLocked 來設定的,沒有直接在ActivityStack裡面實作,:

1.STOPPED的狀态:activityStoppedLocked --> setState(STOPPED)

2.INITIALIZING狀态:new ActivityRecord() --> setState(INITIALIZING)

4.ActivityRecord 狀态變化來改變Activity的狀态

整體狀态變化 Log如下,主要分為3個階段:

第1階段:DeskClock 應用啟動前的準備工作

// 在系統程序裡面,ActivityRecord(DeskClock) 狀态是 INITIALIZING
08-23 17:30:21.261  1314  4528 V ActivityTaskManager: State movement: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t-1} from:null to:INITIALIZING reason:ActivityRecord ctor

// 在系統程序裡面,ActivityRecord(Launcher ) from:RESUMED to:PAUSING
08-23 17:30:21.306  1314  4528 V ActivityTaskManager: State movement: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83} from:RESUMED to:PAUSING reason:startPausingLocked

// 在Launcher應用程序裡面,Activity(Launcher)狀态是onPause 
08-23 17:30:21.322  2055  2055 V Activity: onPause com.android.launcher3.Launcher@cfe111f

// 在系統程序裡面,ActivityRecord(Launcher ) from:PAUSING to:PAUSED
08-23 17:30:21.324  1314  1443 V ActivityTaskManager: State movement: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83} from:PAUSING to:PAUSED reason:completePausedLocked

// 在系統程序裡面,ActivityRecord(DeskClock) 狀态是 from:INITIALIZING to:RESUMED
08-23 17:30:21.398  1314  1443 V ActivityTaskManager: State movement: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87} from:INITIALIZING to:RESUMED reason:minimalResumeActivityLocked
           

第2階段:DeskClock 應用程序建立并進入resume

// 在DeskClock應用程序裡面,Activity(Launcher)狀态是onCreate 
08-23 17:30:21.706  4887  4887 V Activity: onCreate com.android.deskclock.DeskClock@5f58495: null

// 在DeskClock應用程序裡面,Activity(Launcher)狀态是onStart 
08-23 17:30:22.009  4887  4887 V Activity: onStart com.android.deskclock.DeskClock@5f58495

// 在DeskClock應用程序裡面,Activity(Launcher)狀态是onResume 
08-23 17:30:22.016  4887  4887 V Activity: onResume com.android.deskclock.DeskClock@5f58495


           

第3階段:Launcher應用進入onStop

// 在系統程序裡面,ActivityRecord(Launcher ) from:PAUSED to:STOPPING
08-23 17:30:22.955  1314  1443 V ActivityTaskManager: State movement: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83} from:PAUSED to:STOPPING reason:stopActivityLocked

// 在Launcher應用程序裡面,Activity(Launcher)狀态是onStop 
08-23 17:30:22.957  2055  2055 V Activity: onStop com.android.launcher3.Launcher@cfe111f

// 在系統程序裡面,ActivityRecord(Launcher ) from:STOPPING to:STOPPED
08-23 17:30:22.980  1314  2324 V ActivityTaskManager: State movement: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83} from:STOPPING to:STOPPED reason:activityStoppedLocked
           

4.1 第1階段:從桌面啟動DeskClock應用

此時DeskClock的應用程序還未建立,主要是Launcher應用狀态的變化

a) DeskClock的ActivityRecord為INITIALIZING,Activity還未建立

b) Launcher的ActivityRecord狀态RESUMED -->PAUSING --> PAUSED(運作在system_server裡面)

c) Launcher的Activity狀态從onResume --> onPause(運作在Launcher應用程序裡面)

時序圖如下:

android裡面的Activity體系結構(3)_ActivityRecord和Activity狀态變化分析說明

對應的Log段是

// 步驟5:在系統程序裡面,ActivityRecord(DeskClock) 狀态是 INITIALIZING
08-23 17:30:21.261  1314  4528 V ActivityTaskManager: State movement: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t-1} from:null to:INITIALIZING reason:ActivityRecord ctor

// 步驟11:在系統程序裡面,ActivityRecord(Launcher ) from:RESUMED to:PAUSING
08-23 17:30:21.306  1314  4528 V ActivityTaskManager: State movement: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83} from:RESUMED to:PAUSING reason:startPausingLocked

// 步驟13:在Launcher應用程序裡面,Activity(Launcher)狀态是onPause 
08-23 17:30:21.322  2055  2055 V Activity: onPause com.android.launcher3.Launcher@cfe111f

// 步驟14:在系統程序裡面,ActivityRecord(Launcher ) from:PAUSING to:PAUSED
08-23 17:30:21.324  1314  1443 V ActivityTaskManager: State movement: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83} from:PAUSING to:PAUSED reason:completePausedLocked
           

4.2 第2階段:DeskClock應用進入建立并啟動

首先需要了解Android應用程序的建立過程,Zygote fork子程序成功傳回後,會通過反射調用ActivityThread的main方法,具體如下圖(從網上下載下傳的):

android裡面的Activity體系結構(3)_ActivityRecord和Activity狀态變化分析說明

在DeskClock應用程序建立後,主要是DeskClock的狀态變化

DeskClock的ActivityRecord狀态:從from:INITIALIZING to:RESUMED,

Activity依次:從onCreate/onStart/onResume

代碼時序圖如下:

android裡面的Activity體系結構(3)_ActivityRecord和Activity狀态變化分析說明

其中使用到了ClientLifecycleManager來管理Activity生命周期流程

// 步驟7:在系統程序裡面,ActivityRecord(DeskClock) 狀态是 from:INITIALIZING to:RESUMED
08-23 17:30:21.398  1314  1443 V ActivityTaskManager: State movement: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87} from:INITIALIZING to:RESUMED reason:minimalResumeActivityLocked

// 步驟10:在DeskClock應用程序裡面,Activity(Launcher)狀态是onCreate 
08-23 17:30:21.706  4887  4887 V Activity: onCreate com.android.deskclock.DeskClock@5f58495: null

// 步驟13:在DeskClock應用程序裡面,Activity(Launcher)狀态是onStart 
08-23 17:30:22.009  4887  4887 V Activity: onStart com.android.deskclock.DeskClock@5f58495

// 步驟14:在DeskClock應用程序裡面,Activity(Launcher)狀态是onResume 
08-23 17:30:22.016  4887  4887 V Activity: onResume com.android.deskclock.DeskClock@5f58495
           

4.2 第3階段:Launcher應用進入onStop

在DeskClock應用進入resume後,通過binder調用ActivityTaskManagerService.activityIdle來進行Activity的回收,由于在第1階段,Launcher已經是PAUSED狀态,後面會依次将狀态變更為STOPPING和STOPPED

android裡面的Activity體系結構(3)_ActivityRecord和Activity狀态變化分析說明

對應的log流程是:

// 步驟5:在系統程序裡面,ActivityRecord(Launcher ) from:PAUSED to:STOPPING
08-23 17:30:22.955  1314  1443 V ActivityTaskManager: State movement: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83} from:PAUSED to:STOPPING reason:stopActivityLocked

// 步驟6:在Launcher應用程序裡面,Activity(Launcher)狀态是onStop 
08-23 17:30:22.957  2055  2055 V Activity: onStop com.android.launcher3.Launcher@cfe111f

// 步驟9:在系統程序裡面,ActivityRecord(Launcher ) from:STOPPING to:STOPPED
08-23 17:30:22.980  1314  2324 V ActivityTaskManager: State movement: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83} from:STOPPING to:STOPPED reason:activityStoppedLocked
           

繼續閱讀