ActivityManagerService中Activity调度分析一

ActivityManagerService中Activity调度分析一

目录

ActivityManagerService中Activity调度分析一

1 简介

1.1 目的

1.2 范围

2 AMS启动

2.1类结构基础

2.2 Ams启动描述

3 Launcher启动

3.1 TopActivity的一次寻租

3.2 HomeActivty关联Stack及Task的内嵌

3.3 TopActivty的二次寻租

3.4 Process的启动


 

1 简介

 

1.1 目的

基于Android4.4平台,梳理ActivityManagerService服务,了解Android关于Activity信息管理,Activity生命周期的调度,以及其他subsystem信息的反馈交互。

1.2 范围

此文主要涉及到SystemServer启动AMS的流程及关键信息,针对AMS复杂的管理框架,以Launcher启动为契机,分析其流程,作为AMS梳理开篇。

2 AMS启动

AMS作为Android系统的核心服务,承载四大组件的管理调度,其工作流贯穿Android的各个维度,由其是与其它系统服务的交互,分析AMS的启动流程对于后面具体分析有及其重要作用,下面具体展开。

2.1类结构基础

在开始分析AMS前,有必要对AMS体系的关键类结构做一个分析,Ams复杂的管理框架正是基于它们搭建起来的。下图简单的分析了下其类结构

           可以看到,AMS管理框架,对Activity信息管理及调度主要依赖于ActivityStackSupervisor,同时它又依赖于ActivityStack,顾名思义它是一个栈,实际上它是一个基于虚拟栈定义的管理类,通过持有多个TaskRecord来管理Stack内的ActivityRecord,而在这个语境下一个Activity对应多个ActivityRecord(不同的启动方式)。

这里对关键信息做一些记录,ActivityStack如下

 // 1 关键服务对象  

    final ActivityManagerService mService;

    final WindowManagerService mWindowManager;

    /** Run all ActivityStacks through this */

    final ActivityStackSupervisor mStackSupervisor;

    // 2 set集合,

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

    /**3 特殊的Activityrecord

     */
    ActivityRecord mPausingActivity = null;
    ActivityRecord mLastPausedActivity = null;

    // 4 Stack id

    final int mStackId;

如上,这里可以看下TaskRecord的信息

final class TaskRecord extends ThumbnailHolder {

    // 1 核心属性

    final int TaskId;       // Unique identifier for this Task.

    final String affinity;  // The affinity name for this Task, or null.

    Intent intent;          // The original intent that started the

   ..

    /** 2 List of all activities in the Task arranged in history order */

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


    /** Current Stack */

    ActivityStack Stack;


    /** 3 Takes on same set of values as ActivityRecord.mActivityType */

    private int mTaskType;

    /** Launch the home Activity when leaving this Task. */

    boolean mOnTopOfHome = false;

其关键信息是mActivities,它是一个Set,由此来管理Task下的ActivityRecord。另一个Task会从属于一个Stack。这里继续来看下ActivityRecord信息,如下:

final class ActivityRecord {

    // 1 core index

    final ActivityManagerService service; // owner

    final IApplicationToken.Stub appToken; // window manager token

    final ActivityStackSupervisor mStackSupervisor;

    // 2 Activity info

    final ActivityInfo info; // all about me

    final int launchedFromUid; // always the uid who started the Activity.

    final String launchedFromPackage; // always the package who started the Activity.

    final String shortComponentName; // the short component name of the intent

    final String resolvedType; // as per original caller;

    final String packageName; // the package implementing intent's component

    final String processName; // process where this component wants to run

    // 3 type

    static final int APPLICATION_ACTIVITY_TYPE = 0;

    static final int HOME_ACTIVITY_TYPE = 1;

    static final int RECENTS_ACTIVITY_TYPE = 2;

    int mActivityType;

    // 4 record

    ProcessRecord app;      // if non-null, hosting application

    ActivityState state;    // current state we are in

可以看到ActivityRecord主要信息是基于Activity类本身来组织的,同时包含所属的ActivityTypestate等。

 

下面来分析基于这些基础类结构构建的AMS管理架构。

2.2 Ams启动描述

Android4.4在SystemServer来启动众多系统核心服务,AMS也是在其中被启动,托管在SystemServer进程中,这里来按照顺序分析代码:

 

这里可以进入AMS内看下,在Main方法中主要做了什么事情

如描述,其新建了两个关键的对象。接着来继续来看在SystemServer中:

这里通过调用setSystemProcess来初始化系统服务,并将其以及AMS自身注册到ServiceManager,以便其它服务获取AMS的Binder句柄。同时它还处理mPidsSelfLocked,填充一些核心服务信息,这个对象在后面systemNow方法有用到。

这个方法主要是初始化AMS中的contentproviders等

这里可以看到SystemServer调用了systemReady,顾名思义,这个函数意思是AMS做好了系统准备,这里进入ActivityManagerService.java来看下。首先AMS分析pre_boot相关Intent的状态,结合本地化记录,处理它们,如下

 

之后基于传入的runnable对象,开始执行,其具体逻辑在Systemserver中可以看到,主要是系统其它服务的一些预备工作,包括PMS中包信息收集等,这个在下面分析中至关重要。

第二步,从本地及PMS中读取persist声明的App,并启动它们,如下

到这里,基本完成此方法的使命,然后通过方法resumeTopActivitiesLocked来开启Launcher,如下

综上可以看到AMS的启动,伴随着系统服务的启动及预备,至此可以认为整个Android系统已经启动完毕,可以开启服务阶段了。 

3 Launcher启动

接着第二节分析,在AMS启动最后阶段,开启了Launcher启动,基于此流程的分析,同步的可以对AMS的管理调度框架有个初步了解,理解关于Intent,Stack及Task的应用。

在开始之前可以通过下图对其逻辑有个大致的了解。

如上图,基于Launcher的启动,从AMS的管理维度出发,可以将其启动概括的分为下面四个阶段

  1. TopActivity的一次寻租
  2. HomeActivty关联Stack及Task的内嵌
  3. TopActivty的二次寻租
  4. Process的启动

对于Process启动后与AMS的交互,及其带动的生命周期调动在时序图上有反馈,不在本篇文章分析之列。

3.1 TopActivity的一次寻租

首先来分析第一阶段,把它总结为“TopActivity的一次寻租”,主要是指,在AMS中对所有Stack中处于栈顶位置的Actvivity的查找并借用,这个过程涉及到Stack及Task操作,在Ams的systemReady中有

这里通过调用mStackSupervisor的resumeTopActivitiesLocked方法,开启Launcher启动。

这里首先是获取当前的焦点Stack,这也可以理解在AMS中是同时存在多个Stack的,一般查找TopActivity,基本是从焦点所在的Stack或frontStack开始的,在resumeTopActivitiesLocked中,可以看到遍历AMS所持的全部Stacks,同时判断此Stack是否处于前台,只有是前台Stack,才将操作继续交给Stack处理。这里看看,AMS是如何判断是否焦点及frontStack的,如下

可见,在Android中一般AMS只有两个Stack栈。

一般通过目标Stack的stakId来判断是否处于Front位置

回到刚才的话题,通过isfrontStack找到目标Stack后,通过它调用resumeTopActivityLocked来继续处理,进入ActivityStack.java继续分析

可以看到入参中,第一个参数是prev,特指前序Activity对象。这个方法首先通过topRunningActivityLocked查看下个此Stack中的处于栈顶的Activity,此Activity也是最有可能成为TopActivity的选择,我们来看

可以看到,在ActivityStack中,遍历mTaskHistory(Task集合),逐层查找,最终找到顶层Activity,但是由于此时Android是第一次启动,所以mTaskHistory肯定是空的, topRunningActivityLocked返回null。还有一种场景是是TopActivity不是空但不一定是满足后续条件的。

回到ActivityStack的resumeTopActivityLocked方法

这里可以看到,nest对象为空,通过mStackSupervisor对象的resumeHomeActivity,开始下一阶段的查找,至此第一阶段的寻租完成,可以看到此时在所有Stack中并没有合适待选Activity供系统选择。

3.2 HomeActivty关联Stack及Task的内嵌

这里接着分析第二阶段“HomeActivty关联Stack及Task的内嵌”,主要完成HomeActivity关联信息及Stack的内嵌填充,继续分析如下

在ActivityStackSupervisor.java中有

这个方法,主要做的事情如注释,其中通过moveHomeToTop来移动homeStack到栈顶,如下

在ActivityStack中有

一般而言,移栈操作涉及到:1 目标Stack的移动 2 目标Stack内Task的移动

接着ActivityStackSupervisor的resumeHomeActivity方法,最终通过ams的startHomeActivityLocked继续调用,如下

在AMS中,首先通过getHomeIntent去查找显示的Launcher相关Intent(通过PMS来补充足量信息)。

接下来调用mStackSupervisor对象的startHomeActivity方法,继续跟踪如下:

这里直接分析startActivityLocked方法

对于Launcher来说,caller一定是空,继续跟踪此方法

这里省略了前期一些准备工作,接下来基于之前查找的Intent来新建ActivityRecord对象。此时通过Activity调度器来查找焦点Stack。接下来如果Stack的resumeActivity为空且服务不容许在boot阶段做一些耗时操作,可将任务加入一个队列返回待后期执行。这里来看下条件为假的case,此时直接调用startActivityUncheckedLocked方法,继续来分析此方法

 

这里主要是对Intent中Flag参数的校正

这里可以看到许多局部变量,顾名思义,这里主要是为了寻找相关的Task等,如上图中标注,那里基于给定的record来查找可替代的record

由其逻辑显示,此时反馈null(首次Stack中Task集合为空),继续分析,接上个方法,此时反馈的intentActivity为空

这里,在首次启动Launcher时,其判断条件为真,进入逻辑后,首先在调度器内移栈(某些场景下需要创建Stack)。接下来基于Record信息来在焦点Stack中构造Task,这个比较关键。我们继续来看

可以看到,通过ActivityStack的createTaskRecord方法,完成了两件事情:创建Task对象,添加Task对象到焦点Stack中去。

继续来分析:

最后通过焦点Stack的方法来处理相关逻辑,进入ActivityStack跟踪如下

继续分析此方法有:

这里可以看到,此时将对应的ActivityRecord对象添加到Task中(极其关键),继续分析有:

最终又调用=到了调度器的resumeTopActivitiesLocked方法,这个应该似曾相识,之前在第一阶段有介绍到,只不过目前AMS涉及的管理框架的内部状态不同了,主要表现在:

  1. HomeStack新建完成
  2. HomeStack中的Task建立并排序
  3. 关联Task中添加了Launcher的ActivityRecord对象

至此完成第二阶段的分析.

3.3 TopActivty的二次寻租

 

下面开始分析第三阶段“TopActivty的二次寻租”,顾名思义是区别于第一次寻租,此时根据第二阶段分析,可以找到可选目标Activity了。这里进入ActivityStackSupervisor.java 中,重新分析方法resumeTopActivitiesLocked,根据第一阶段分析,此时直接进入焦点Stack的resumeTopActivityLocked方法,根据第二阶段分析,此时的焦点Stack是HomeStack,下面继续展开来看

进入ActivityStack.java有:

此时通过topRunningActivityLocked方法查找可选Activity,此时next不为空,且其内容为第二阶段填充的Launcher。接下来:

这里做了两件事:

1 对调度器中的全局ActivityRecord状态进行维护。

2 通过调度器对次时焦点Activity进行Pause动作(在这个语境下还没焦点Acitivity)。

继续在此语境下分析,其逻辑:

如上图ActivityRecord的processRecord肯定为空,这时调用调度器的startSpecificActivityLocked方法继续进行。

继续跟踪有:

这里首先通过AMS来查找此ActivityRecord关联的ProcessRecord对象,这里肯定为空,根据逻辑调用AMS的startProcessLocked方法,入参有与ActivityRecord关联的compent信息。而且根据方法名应该知道此时要启动对应的process了,至此完成了第三阶段的分析,这个阶段,寻租到核实ActivityRecord,并完成相关的状态维护,并开启process逻辑。

 

3.4 Process的启动

接下来分析第四阶段“Process启动”,任何Android组件最终都要挂接在一个进程中,这是非常重要的,虽然Android一直在弱化进程的概念,凸显组件化的理念。接着上面分析,我们来看下AMS逻辑

首先通过getProcessRecordLocked来查找对应的process记录,根据上面的分析,在Launcher下,此时对应process对象为NULL,继续分析此方法:

这里新建ProcessRecord对象,并添加到全局队列中

这里调用了startProcessLocked方法,此时入参是刚刚构建的对象,继续分析

这里忽略了前面关于参数格式的校正及获取,直接调用Process的start方法,其中入参是ActivityThread的路径字符串,这里很关键。

在Process中,start会通过socket发送信息到远程服务Zygote来孵化Android进程,然后利用反射调用processClass的main()方法,其实就是ActivtyThread类。接着在第三方进程中通过IPC来与AMS交互推动常驻在三方进程中Activity生命周期的流转,这里就不具体展开了。

 

至此就完成四个阶段的分析了,本篇文章通过Launcher启动为入口,简单的来分析AMS管理调度框架的逻辑,是学习AMS的开端,为后期AMS其它子模块分析奠定了基础。关于二级Activity的启动回退及数据流分析,请参考Activity调度分析二

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值