ActivityManagerService源码探究

作者: 马也程序猴 | 来源:发表于2021-07-19 21:49 被阅读0次

    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来说是一致的。

    ActivityStatck结构图

    到了这里,AMS的相关内容就梳理了一遍了,还有更多的内容在源码中,感兴趣的朋友可以深入的阅读。

    这次了解了访问AMS的路径,AMS创建的过程,以及AMS中一些主要的内容;而ASM的主要工作也就是对应Activity的一系列操作了,在最初阅读源码时也接触过了Activity的启动过程,这里面就是主要就是AMS处理的工作。

    相关文章

      网友评论

        本文标题:ActivityManagerService源码探究

        本文链接:https://www.haomeiwen.com/subject/jvqkmltx.html