天天看點

ActivityManagerService源碼探索

Activity可以說是我們開發Android最早接觸的内容了,那麼系統是怎樣建立、維護Activity的,整個應用中的Activity是怎樣管理的,這些工作系統都交給了ActivityManagerService來完成,簡稱AMS。

AMS的好朋友們

AMS全稱ActivityManagerService,顧名思義它和Activity的關系一定不淺,那麼要了解AMS,從Activity入手一定沒錯。 在Instrumentation類中,有一個execStartActivity方法,在Activity的啟動過程中會調用到它,而這個過程就有AMS的參與。

//Instrumentation源碼節選
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
    // ...省略部分...
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        // 使用ActivityManager調用getService()擷取AMS 注釋點:1
        int result = ActivityManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,
            intent.resolveTypeIfNeeded(who.getContentResolver()),
            token, target != null ? target.mEmbeddedID : null,
            requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}
    
// ActivityManager源碼節選
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
    new Singleton<IActivityManager>() {
        @Override
        protected IActivityManager create() {
            // 注釋點:2
            final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
            // 注釋點:3
            final IActivityManager am = IActivityManager.Stub.asInterface(b);
            return am;
        }
};
    
    
           

注釋點1ActivityManager中的getService傳回的是IActivityManager類型内容,而ServiceManager擷取的Service也就是AMS;注釋3它是以AIDL的方式擷取的,那麼我們可以合理推測出來,AMS是繼承于IActivityManager.Stub類的。

同時以上的内容也是外部擷取AMS的方式,通過ActivityManager.getService()來擷取AMS對象。注釋2也能看到,AMS是由ServiceManager擷取的,而ServiceManager内部緩存了不同的Service對象,根據Service名稱來存取,AMS也會緩存在其中。

AMS的好朋友就非ActivityManager莫屬了,聰明的朋友光看名字都猜出了大概;實際上在Android7的源碼中,AMS不隻有ActivityManager陪伴,還有ActivityManagerNative和ActivityManagerProxy一起配合,隻是在Android8之後由AIDL簡化了這個過程,感興趣的朋友可以找到源碼看下這塊。

為什麼不直接使用AMS而要通過另外一個類來使用它,這個問題和AMS的啟動有關,我們接着往下看。

AMS的啟動過程

AMS是一個作為Service來提供服務的對象,前面也提到了,它的使用是外界通過ActivityManager來進行的,而ActivityManager中getService()是一個靜态方法,那麼也就是說AMS啟動的時間點會比較靠前。

前面ActivityManager源碼中我們看到了,其内部的getService()是通過ServiceManager來擷取AMS的,而ServiceManager的内部是有緩存各類Service的,那麼我們找到存入AMS的邏輯,也就找到了AMS啟動的線索。

// AMS源碼節選
public void setSystemProcess() {
    try {
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
    }
}

           

在AMS内部找到setSystemProcess()方法,它的内部就是ServiceManager加入AMS的邏輯,那麼我們再跟随着setSystemProcess()往上查找,緊接着就是SystemService,看名字就能認出它,這是系統服務類,我們再往内部探索一下。

// SystemService
private void startBootstrapServices() {
    
    // ...省略部分...

    // Activity manager runs the show.
    traceBeginAndSlog("StartActivityManager");
    mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
    // 注釋1
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    // 注釋2
    mActivityManagerService.setInstaller(installer);
    traceEnd();

    // ...省略部分...

    // Set up the Application instance for the system process and get started.
    traceBeginAndSlog("SetSystemProcess");
    // AMS内部将自身存入ServiceManager
    mActivityManagerService.setSystemProcess();
    traceEnd();

    // ...省略部分...
}
           

好家夥,它直接明牌了。SystemServiceManager對象非常直接的調用了startService(),而它啟動的就是我們一直探尋的AMS,AMS啟動後直接調用了兩個方法,看看都做了哪些操作。

注釋1:AMS内部維護了SystemServiceManager的對象引用,會使用它來進行一些通知和狀态擷取,這裡先不展開了。

注釋2:設定Installer的對象引用,這是SystemManager的子類,管理應用的安裝邏輯

關于SystemService的啟動,看到網上的解析需要追溯到Zygote,Zygote在啟動Binder保證程序間通信能力後,就會調用SystemService的main方法,之後SystemService就會調用自身的run(),接着就到了上面提到的**startBootstrapServices()**了。

AMS的内容

說過了AMS的前世和情緣,接下來就要好好看看AMS的今生了。那麼AMS除了啟動Activity外,還承擔了哪些重要的工作。

程序檢查

AMS在運作應用程式之前會檢查程式需要運作的程序,對應程序已經存在的情況下,就會直接運作應用程序;但是當程序不存在時,Service會通知Zygote來啟動對應的程序,之後再啟動對應的應用程式。

AMS組成

AMS中有很多組成内容,和Activity有關的就包含了ActivityRecord、TaskRecord、ActivityStack。這三個内容各自維護了和Activity有關的内容,我們詳細來看看。

  • ActivityRecord
/**
 * An entry in the history stack, representing an activity.
 */
final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener {

    final ActivityManagerService service; // owner
    
    final ActivityInfo info; // all about me
    
    final String launchedFromPackage; // always the package who started the activity.
    
    final String taskAffinity; // Activity預想進入的棧
    
    private TaskRecord task;        // 目前Activity所在的TaskRecord
    
    ProcessRecord app;      // 應用程序Record
    
    private ActivityState mState;    // 目前Activity的狀态

    // ...内容...
}
           

ActivityRecord主要用來存儲一些和Activity有關的資訊,一些常用的内容包括service表示AMS的引用、ActivityInfo主要是描述AndroidManifest中注冊Activity時的聲明内容;

可以看到ActivityRecord中是會儲存它所在棧對應的TaskRecord對象的引用的,那麼我們接着來看TaskRecord

  • TaskRecord
class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {

    final int taskId;       // Unique identifier for this task.

    final ArrayList<ActivityRecord> mActivities;    // Task内部ActivityRecord集合

    private ActivityStack mStack;   // 目前所在的棧對象

    final ActivityManagerService mService;  // AMS應用

           

TaskRecord中又儲存了ActivityStack對象,也就是棧對象;而我們知道,應用在運作中是會維護Activity棧的,我們再來看下ActivityStack的内容,嘗試梳理一下它們的關系。

  • ActivityStack
class ActivityStack<T extends StackWindowController> extends ConfigurationContainer
        implements StackWindowListener {
    
    // Activity的各種狀态
    enum ActivityState {
        INITIALIZING,
        RESUMED,
        PAUSING,
        PAUSED,
        STOPPING,
        STOPPED,
        FINISHING,
        DESTROYING,
        DESTROYED
    }

    private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();

    final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
           

可以看到ActivityStack中儲存了TaskRecord的集合;同時還儲存了一份ActivityRecord,并且根據命名來看,這份集合的儲存方式是按照LRU算法來維護的,這一點比較我們的Recent Activity來說是一緻的。

ActivityManagerService源碼探索

到了這裡,AMS的相關内容就梳理了一遍了,還有更多的内容在源碼中,感興趣的朋友可以深入的閱讀。

這次了解了通路AMS的路徑,AMS建立的過程,以及AMS中一些主要的内容;而ASM的主要工作也就是對應Activity的一系列操作了,在最初閱讀源碼時也接觸過了Activity的啟動過程,這裡面就是主要就是AMS處理的工作。