剖析ActivityManagerService



做爲Android開發的你,對Activity的使用確定是再熟悉不過了,在使用過程當中,你是否浮現過一個疑問:java

系統是如何管理這些Activity的?

沒錯,該文將與你一塊兒探索ActivityManagerService(如下簡寫爲AMS),看它是如何管理Activity的。android

該文主要圍繞如下三方面來討論:shell

該文主線.png

先基本瞭解下AMS是什麼?數據結構

  • AMS是Android系統的一個進程;
  • 用於管理系統四大組件的運行狀態;

1、AMS的啓動流程?

AMS的初始化,這裏我打算拿API 19(Android 4.4) 和 API 25(Android 7.1.1)的源碼進行對比。ide

在API 19源碼中,隨着SystemServer類main()方法的調用,實例化了內部類ServerThread的對象:oop

代碼1.1 (來源:  SystemServer.java):

public static void main(String[] args) {
    ......(省略了一小戳代碼)
    ServerThread thr = new ServerThread();
    thr.initAndLoop();
}

咱們繼續看內部類ServerThread的initAndLoop()方法,看到這方法不得不吐槽一番,整個方法竟有長達1000+行代碼,真不知道這碼農是否是屁股癢了:this

代碼1.2 (來源:  SystemServer.java):

public void initAndLoop() {
    ......
    context = ActivityManagerService.main(factoryTest);
    ......
    ActivityManagerService.setSystemProcess();
}

該方法但是很是的強大哦,諸多系統級的服務都在此初始化,如AMS、PowerManagerService、WindowManagerService、NetworkManagementService等等,有興趣的能夠去細細品味源碼。
好了,繼續重點,調用ActivityManagerService的靜態方法main(),便可獲得AMS的上下文。spa

代碼1.3 (來源:  ActivityManagerService.java):

public static final Context main(int factoryTest) {
    // 建立了一個AThread線程,並開啓
    AThread thr = new AThread();
    thr.start();

    synchronized (thr) {
        while (thr.mService == null) {
            try {
                thr.wait();
            } catch (InterruptedException e) {
            }
        }
    }

    ActivityManagerService m = thr.mService;
    mSelf = m;
    ActivityThread at = ActivityThread.systemMain();
    mSystemThread = at;
    Context context = at.getSystemContext();

    m.mContext = context;
    ......

    return context;
}

這段代碼,不知道你有沒有發現,雖然它開啓了Athread線程,可是它立馬又進入了等待狀態,這是爲何呢?默默想10秒鐘。.net

由於下面須要使用到AMS的對象,若是AMS的對象還未初始化,咱們貿然使用,那確定會致使系統宕機。因此,可想而知,AThread中確定對AMS進行了實例化,那等待的線程如何去喚醒它呢?答案就在下面,繼續看看線程AThread的實現:線程

代碼1.4 (來源:  ActivityManagerService.java):

static class AThread extends Thread {
    ActivityManagerService mService;

        public AThread() {
            super("ActivityManager");
        }

        @Override
        public void run() {
           ......
            // 實例化了AMS對象
            ActivityManagerService m = new ActivityManagerService();

            synchronized (this) {
                mService = m;
                notifyAll();
            }

         ......
        }
    }

以上代碼中,實例化了AMS對象並賦值給mService,notifyAll()的職責就是對等待的AThread線程進行喚醒,此時便可跳出代碼1.3中的while循環,然後返回context。
而後調用ActivityManagerService.setSystemProcess();便可向Server Manager註冊,到此AMS的整個啓動流程到此結束。

剛咱們一塊兒瞭解了在API 19下的AMS啓動流程,那和API 25下的源碼相比較,有何改變呢?下面一塊兒來看看吧。
       一樣是SystemServer類的main()方法,可是一行簡單代碼了事。

代碼1.5 (來源:  SystemServer.java):

public static void main(String[] args) {
   new SystemServer().run();
}
代碼1.6 (來源:  SystemServer.java):

private void run() {
   ......
   // 在這裏啓動各類系統級服務
   startBootstrapServices();
   startCoreServices();
   startOtherServices();
   ......
}
代碼1.7 (來源:  SystemServer.java):

private void startBootstrapServices() {
    ......
    // 這裏直接經過SystemServiceManager直接開啓AMS
    mActivityManagerService = mSystemServiceManager.startService(
    ActivityManagerService.Lifecycle.class).getService();
                
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    ......
}
代碼1.8 (來源:  ActivityManagerService.java):

public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            // 獲得了AMS的實例
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            mService.start();
        }

        public ActivityManagerService getService() {
            return mService;
        }
}

看見沒,API 25的源碼相比API 19來講,通俗易懂,給贊,因此也無需多作解釋了,有興趣的能夠打開源碼仔細研究哦。

2、Activity Stack介紹

Stack意爲堆棧,做爲Activity的堆棧,主要仍是由如下三大部分組成。

2.1 Activity State

該枚舉類定義的各類狀態和Activity的生命週期有着千絲萬縷的關係。

代碼2.1 (來源:  ActivityStack.java):

enum ActivityState {
     INITIALIZING,    // 初始化中
     RESUMED,         // 恢復
     PAUSING,         // 暫停中
     PAUSED,          // 已暫停
     STOPPING,        // 中止中
     STOPPED,         // 已中止
     FINISHING,       // 完成中
     DESTROYING,      // 銷燬中
     DESTROYED        // 已銷燬
}

2.2 ArrayList

在Activity Stack中定義了一些ArrayList,用來保存特定狀態的Activity,好比:

代碼2.2 (來源:  ActivityStack.java):

ArrayList<TaskRecord> mTaskHistory;
ArrayList<TaskGroup> mValidateAppTokens;
ArrayList<ActivityRecord> mLRUActivities;
ArrayList<ActivityRecord> mNoAnimActivities;
ArrayList<ActivityRecord> mStoppingActivities;
ArrayList<ActivityRecord> mFinishingActivities;
......

2.3 記錄特殊狀態下的Activity

代碼2.3 (來源:  ActivityStack.java):

ActivityRecord mPausingActivity = null;
ActivityRecord mLastPausedActivity = null;
ActivityRecord mLastNoHistoryActivity = null;
ActivityRecord mResumedActivity = null;
ActivityRecord mLastStartedActivity = null;
......

正由於有了這三大部分,AMS便可經過Activity Stack實現了對系統組件的記錄、管理以及查詢功能。

小技巧:
在控制檯輸入如下命令,便可查看Activity Stack的信息

adb shell dumpsys activity

3、Activity Task介紹

Activity Task的數據結構相似堆棧,遵循「先入後出」的原則,它負責裝載執行同一任務的Activity實例集合,下面咱們將拿Activity的四種launchMode來具體講解。

相信不少人對Activity的launchMode都有所瞭解,可是在使用的時候總會有些含糊不清,以下圖:

Activity的四種啓動模式.png

對各啓動模式的特色有所瞭解以後,接下來就逐一進行剖析。

3.1 standard【"富二代"】

standard.png

從上圖Task的變化便可看出,每次操做都會將新的實例壓入棧頂,返回的時候剔除棧頂元素,全部操做都在同一個Task中完成。

經過在控制檯輸入adb shell dumpsys activity,就會打印諸多堆棧信息,從中咱們能夠找到如下信息便可印證上述結論:

standard_log.png

3.2 singleTop【"近視眼"】

當將OneActivity在AndroidManifest.xml中配置以下:

代碼3.2 :

<activity android:name=".OneActivity"
            android:launchMode="singleTop">

singleTop.png

兩種狀況打印日誌以下:

singleTop_one.png

singleTop_two.png

3.3 singleTask【"特工"】

SingleTask.png

在上圖中,除將OneActivity的啓動模式設置爲SingleTask外,其他都默認。當咱們在ThreeActivity中打開OneActivity的時候,由於在Task中已經存在了OneActivity的實例,因此會直接將Intent經過onNewIntent傳遞給已存在的實例,而且會將它上面的其它全部實例從該堆棧中剔除,將本身暴露在棧頂。

咱們來看看控制檯打印的堆棧信息變化:

SingleTask_log_one.png

SingleTask_log_two.png

3.4 singleInstance【"霸道總裁"】

singleInstance.png

從上圖能夠看出,TwoActivity會獨佔一個新的Task,而且不容許其它實例加入進來。咱們來看看控制檯的日誌信息:

singleInstance.png

到此,Activity的四種啓動模式就講解完了。

縱觀全篇,咱們始終圍繞「AMS的啓動流程」、「Activity Stack介紹」和「Activity Task介紹」三方面來展開討論,若有疏漏,望批評指正。


相關文章
相關標籤/搜索