谈AMS的诞生和使用

简介: 今天接着完善Android系统这一块的体系架构,说说在App启动流程中举足轻重的ActivityManagerService。

前言


今天接着完善Android系统这一块的体系架构,说说在App启动流程中举足轻重的ActivityManagerService


顾名思义,这个组件肯定是用来管理Activity的服务,其实不仅是Activity,它还负责四大组件相关的启动,切换,调度等等。


具体是怎么被启动的,又是怎么进行管理的呢?一起看看吧。


(代码基于Android9.0)


服务的启动


之前在SystemServer章节说过,系统的服务一般都是通过SystemServer进程启动的,AMS也不例外。


//SystemServer.java
    private void startBootstrapServices() {
        //...
        // Activity manager runs the show.
        traceBeginAndSlog("StartActivityManager");
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        traceEnd();
    }
    //中间用到了反射,之前说过。
    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
    }    
//ActivityManagerService.java
    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;
        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);
        }
        @Override
        public void onStart() {
            mService.start();
        }
        @Override
        public void onBootPhase(int phase) {
            mService.mBootPhase = phase;
            if (phase == PHASE_SYSTEM_SERVICES_READY) {
                mService.mBatteryStatsService.systemServicesReady();
                mService.mServices.systemServicesReady();
            }
        }
        @Override
        public void onCleanupUser(int userId) {
            mService.mBatteryStatsService.onCleanupUser(userId);
        }
        public ActivityManagerService getService() {
            return mService;
        }
    }


可以看到,通过调用了ActivityManagerService.Lifecycle这个内部类中的onStart方法,启动了AMS,并调用了AMS的start方法。


再简单看看AMS的实例化方法start方法:


public ActivityManagerService(Context systemContext) {
        mContext = systemContext;
        mFactoryTest = FactoryTest.getMode();
        mSystemThread = ActivityThread.currentActivityThread();
        mUiContext = mSystemThread.getSystemUiContext();
        mHandlerThread = new ServiceThread(TAG,
                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
        mHandlerThread.start();
        mHandler = new MainHandler(mHandlerThread.getLooper());
        mUiHandler = mInjector.getUiHandler(this);
        //...
        mServices = new ActiveServices(this);
        mProviderMap = new ProviderMap(this);
        mAppErrors = new AppErrors(mUiContext, this);
        // TODO: Move creation of battery stats service outside of activity manager service.
        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
        mBatteryStatsService.getActiveStatistics().readLocked();
        mBatteryStatsService.scheduleWriteToDisk();
        mOnBattery = DEBUG_POWER ? true
                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
        mBatteryStatsService.getActiveStatistics().setCallback(this);
        mStackSupervisor = createStackSupervisor();
        mStackSupervisor.onConfigurationChanged(mTempConfig);
        mActivityStartController = new ActivityStartController(this);
        mRecentTasks = createRecentTasks();
        mStackSupervisor.setRecentTasks(mRecentTasks);
        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
        mLifecycleManager = new ClientLifecycleManager();
        mProcessCpuThread = new Thread("CpuTracker")
        //...
    }
    private void start() {
        removeAllProcessGroups();
        mProcessCpuThread.start();
        mBatteryStatsService.publish();
        mAppOpsService.publish(mContext);
        Slog.d("AppOps", "AppOpsService published");
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
        // Wait for the synchronized block started in mProcessCpuThread,
        // so that any other acccess to mProcessCpuTracker from main thread
        // will be blocked during mProcessCpuTracker initialization.
        try {
            mProcessCpuInitLatch.await();
        } catch (InterruptedException e) {
            Slog.wtf(TAG, "Interrupted wait during start", e);
            Thread.currentThread().interrupt();
            throw new IllegalStateException("Interrupted wait during start");
        }
    }


代码很长,我只截取了一部分。


在构造函数中,主要初始化了一些对象,比如Context、ActivityThrad、Handler、CPU监控线程,还有一些后文要用到的ActivityStackSupervisor、ActivityStarter等对象,


start方法中,主要就是启动了CPU监控线程,然后注册了电池状态服务和权限管理服务。


初始工作


AMS被启动之后,还会在SystemServer启动三大服务的时候偷偷干一些工作,我们搜索下mActivityManagerService变量就可以看到:


private void startBootstrapServices() {
     //1、初始化电源管理器
        mActivityManagerService.initPowerManagement();
        //2、为系统进程设置应用程序实例并启动。
        mActivityManagerService.setSystemProcess();
    }
    private void startCoreServices() {
        // 启动UsageStatsManager,用于查询应用的使用情况
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
        traceEnd();
    }
    private void startOtherServices() {
     //安装系统的Providers
        mActivityManagerService.installSystemProviders();
        //启动WMS,并为AMS设置WMS关系
        wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                    !mFirstBoot, mOnlyCore, new PhoneWindowManager());
        mActivityManagerService.setWindowManager(wm);
        //...
    }
    public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
        }
    }


其中第二步setSystemProcess方法中,会注册AMS到ServiceManager中,这样后续如果需要用到AMS的时候就可以通过ServiceManager进行获取,下面马上就要讲到。


启动就说这么多,都是比较枯燥的内容,所以也没有深入下去,有个印象就行,以后如果需要用到相关知识就知道去哪里找了。


从启动流程看AMS工作内容


为了了解AMS的具体工作,我们就从Activity的启动过程看起。


上文app启动流程中说过,startActivityForResult方法会转到mInstrumentation.execStartActivity方法:


//mInstrumentation.execStartActivity
    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);
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };


可以看到,最终要拿到AMS的IBinder类型引用,这里的ServiceManager.getService(Context.ACTIVITY_SERVICE)是不是有点熟悉,没错,就是刚才专门调用了setSystemProcess方法对AMS进行了注册在ServiceManager中。然后我们要使用相关服务的方法的时候,就通过Servermanager拿到对应服务的引用。


这里也就是拿到了IActivityManager对象,IActivityManager其实就是AMS在当前进程的代理,这里的逻辑就是通过AIDL做了一个进程间的通信。因为这些服务,包括我们今天说的AMS都是在SystemServer进程中的,而我们实际用到的时候是在我们自己的应用进程中,所以就涉及到进程间通信了,这里是用的Binder机制进行通信。


Binder,ServiceManager,这是Binder通信一整套流程,不光是AMS,包括其他的WMS等服务基本上都是通过Binder机制进行进程间通信的,具体内容可以期待下后面说到的Binder章节。


接着看启动流程,通过Binder调用到了AMS的startActivity方法,然后会调用到ActivityStarter的startActivity方法,在这个方法中,我们发现一个新的类:


//ActivityStarter.java
private int startActivity(...){
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }
        //...
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity);    
}


ActivityRecord


这个类翻译过来是Activity的记录,所以猜测是和Activity有关,我们点进去看看它里面包含了什么:


final ActivityManagerService service; // owner
    final IApplicationToken.Stub appToken; // window manager token
    final ActivityInfo info; // all about me
    ApplicationInfo appInfo; // information about activity's app
    final int userId;          // Which user is this running for?
    final String packageName; // the package implementing intent's component
    final String processName; // process where this component wants to run
    final String taskAffinity; // as per ActivityInfo.taskAffinity
    private int icon;               // resource identifier of activity's icon.
    private int logo;               // resource identifier of activity's logo.
    private int theme;              // resource identifier of activity's theme.
    int launchMode;         // the launch mode activity attribute.


我保留了一些比较常用的属性,大家应该都看得出来是什么了吧,比如当前Activity的主题——theme,当前Activity的token——apptoken,当前Activity的包名——packageName


所以这个ActivityRecord其实就是保存记录了Activity的所有信息。


接着看流程,后续会执行到startActivityUnchecked方法,这个方法中,我们又可以看到一个新的类——TaskRecord.


TaskRecord


private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            // This not being started from an existing activity, and not part of a new task...
            // just put it in the top task, though these days this case should never happen.
            setTaskToCurrentTopOrCreateNewTask();
        }
}
// 新建一个任务栈
    private void setTaskToCurrentTopOrCreateNewTask() {
        //...
        final ActivityRecord prev = mTargetStack.getTopActivity();
        final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
                mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
                mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
        addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
        mTargetStack.positionChildWindowContainerAtTop(task);
    }
    //添加Ac到栈顶
    private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
        if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
            parent.addActivityToTop(mStartActivity);
        } else {
            mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
        }
    }


从代码中可知,当我们启动的Activity需要一个新的任务栈的时候(比如启动模式为FLAG_ACTIVITY_NEW_TASK),我们会走到setTaskToCurrentTopOrCreateNewTask方法中,新建一个TaskRecord类,并且把当前的Activity通过addActivityToTop方法添加到栈顶。


所以这个TaskRecord类就是一个任务栈类了,它的作用就是维护栈内的所有Activity,进去看看这个类有哪些变量:


final int taskId;       // Unique identifier for this task.
    /** List of all activities in the task arranged in history order */
    final ArrayList<ActivityRecord> mActivities;
    /** Current stack. Setter must always be used to update the value. */
    private ActivityStack mStack;


这里截取了一些,可以发现有任务id——taskId,任务栈的所有ActivityRecord——mActivities,以及这个还不知道是什么的但是我知道是用来管理所有Activity和任务栈的大管家——ActivityStack。


ActivityStack


启动流程再往后面走,就会走到的ActivityStackSupervisorresumeFocusedStackTopActivityLocked方法:


//ActivityStackSupervisor.java
    /** The stack containing the launcher app. Assumed to always be attached to
     * Display.DEFAULT_DISPLAY. */
    ActivityStack mHomeStack;
    /** The stack currently receiving input or launching the next activity. */
    ActivityStack mFocusedStack;
    /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
     * been resumed. If stacks are changing position this will hold the old stack until the new
     * stack becomes resumed after which it will be set to mFocusedStack. */
    private ActivityStack mLastFocusedStack;
    public ActivityStackSupervisor(ActivityManagerService service, Looper looper) {
        mService = service;
        mLooper = looper;
        mHandler = new ActivityStackSupervisorHandler(looper);
    }
    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || !r.isState(RESUMED)) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.isState(RESUMED)) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }


ActivityStackSupervisor是一个管理ActivityStack的类,在AMS的构造方法中被创建,这个类中可以看到有一些任务栈,比如mHomeStack——包含了Launcher APP的Activity。


然后再看看ActivityStack这个大管家家里存储了什么好东西:


enum ActivityState {
        INITIALIZING,
        RESUMED,
        PAUSING,
        PAUSED,
        STOPPING,
        STOPPED,
        FINISHING,
        DESTROYING,
        DESTROYED
    }
    private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
    final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
    ActivityRecord mPausingActivity = null;
    ActivityRecord mLastPausedActivity = null;


可以看到,在ActivityStack中:


  • 有一个枚举ActivityState,存储了Activity的所有状态。
  • 有一些TaskRecord和ActivityRecord的列表,比如mTaskHistory——没有被销毁的任务栈列表,mLRUActivities——通过LRU计算的列表头目是最近最少使用的Activity的ActivityRecord列表。
  • 还有一些特殊状态的Activity对应的ActivityRecord,比如正在暂停的Activity,上一个暂停过的Activity。


最后,启动流程会走到AMS的startProcessLocked方法,然后跟Zygote进程通信,fork进程。后续就不说了。


总结


到此,AMS中重要的三个组件我们都接触过了,分别是:


  • 管理Activity所有信息的ActivityRecord
  • 管理一个或者多个ActivityRecord的任务栈TaskRecord.
  • 管理一个或者多个任务栈的管理者ActivityStack


再来画个图总结下:


16.png


其实AMS里面的逻辑还有很多很多,不仅是Activity,还有其他三大组件的一些启动调度流程都是通过AMS完成的,还有Activity任务栈相关的内容(包括taskAffinity、allowTaskReparenting),后续具体涉及到的时候会再细谈。


拜拜啦👋


Android体系架构


思维导图链接


参考


《Android进阶解密》 https://juejin.cn/post/6916039838470766606


目录
相关文章
|
1月前
|
存储 Linux Android开发
Android底层:通熟易懂分析binder:1.binder准备工作
本文详细介绍了Android Binder机制的准备工作,包括打开Binder驱动、内存映射(mmap)、启动Binder主线程等内容。通过分析系统调用和进程与驱动层的通信,解释了Binder如何实现进程间通信。文章还探讨了Binder主线程的启动流程及其在进程通信中的作用,最后总结了Binder准备工作的调用时机和重要性。
Android底层:通熟易懂分析binder:1.binder准备工作
|
前端开发 JavaScript Android开发
《移动互联网技术》第五章 界面开发: 掌握Activity的基本概念,Activity的堆栈管理和生命周期
《移动互联网技术》第五章 界面开发: 掌握Activity的基本概念,Activity的堆栈管理和生命周期
104 0
|
JSON JavaScript 数据可视化
Android打造专有hook,让不规范的代码扼杀在萌芽之中
正所谓规范是一个项目的基石,也是衡量一个项目,是否健壮,稳定,可维护的标准,可谓是相当重要的。我相信,大部分的公司都有自己的一套规范标准,我也相信,很多可能就是一个摆设,毕竟人员的众多,无法做到一一的约束,如果采取人工的检查,无形当中就会投入大量的时间和人力成本,基于此,所谓的规范,也很难执行下去。
121 1
|
Java 调度 Android开发
android体系课-系统启动流程-之zygote进程启动过程源码分析
笔者刚开始学习Android的时候也和大部分同学一样,只会使用一些应用层面的知识,对于一些比较常见的开源框架如<mark>RxJava</mark>,<mark>OkHttp</mark>,<mark>Retrofit</mark>,以及后来谷歌推出的<mark>协程</mark>等,都只在使用层面,对于他们<mark>内部原理</mark>,基本没有去了解觉得够用就可以了,又比如Activity,Service等四大组件的使用原理,系统开机过程,Launcher启动过程等知之甚少,知其然而不知其所以然,结果就是出现某些问题,不知道从哪里找原因,只能依赖万能的百度,但是百度看多了,你会发现自己
|
存储 缓存 Java
Android Binder机制原理(史上最强理解,没有之一)
原文地址: http://blog.csdn.net/universus/article/details/6211589   Binder是Android系统进程间通信(IPC)方式之一。
2665 0
|
Web App开发 人工智能 小程序
|
Web App开发 编解码 前端开发
小程序的鼻祖在国内就这么消亡了!(一)
互联网发展了这么久,我们记住了“Native App”、“小程序”、“快应用”、“App clips”、“Hybrid App”、“Web App”,似乎独独没有 PWA,但 PWA 及其理念却一直在推动着前端领域前进。
148 0
小程序的鼻祖在国内就这么消亡了!(一)
|
Web App开发 缓存 前端开发
|
Android开发 Go API
Android系统消息分发体系
Handler、Looper、Message、MessageQueue之间的关系(基于Android API 26)         安卓系统设计的消息分发体系,不仅在应用层广泛应用;而且在底层也是使用这个体系,与Binder一起进行消息分发,因此熟悉这个体系是十分必要的。
1223 0