ActivityManagerService中Activity调度分析二

ActivityManagerService中Activity调度分析二

关于AMS中Activity调度基础请参看Activity调度分析一

目录

ActivityManagerService中Activity调度分析二

1 简介

1.1范围

1.2 目的

2 APP启动分析

2.1 App启动

2.2 AMS管理过程

3 Activity调度分析

3.1 进程内Activty启动

3.2 进程内Activity回退


 

1 简介

1.1范围

基于Android4.4平台,分析首次启动第三方App关键流程,重点关注AMS在这个过程中,是如何组建Stack,Task及ActivityRecord的。在此基础上通过分析三方进程内Activity启动,来理解AMS多场景的管理能力。

 

1.2 目的

通过分析AMS的核心流程来认识AMS的本质,本文接着AMS第一篇分析,在上文中通过AMS中Launcher启动分析,已经了解了AMS框架管理的关键类及基本的调度逻辑,这篇文章在此基础上,通过第三方APP启动及调度分析,来理解AMS对多Stack及Activity场景处理。另外对于单Activity的启动模式,如何基于AMS管理框架对Activity施加影响也会涉及到。

 

2 APP启动分析

这里将介绍三方APP启动流程,重点围绕在全过程的流程梳理,在分析过程中将忽略第一篇介绍内容,着重凸显AMS统一的管理过程

2.1 App启动

首先通过下图来看下,App启动的全链路过程,结合第一篇文章中对Launcher启动分析,可以初步看到Ams在Actvity管理中固定的一些流程。

 区别于Launcher启动,首次Activity启动,其ActivityInfo的构造依赖于入参Intent,而不同于Launcher中Intent全局搜索。其次是在ActivityStack通过resumeTopActivityLocked方法启动Activity时,流程的差异。下面主要来看第二点,也就是resumeTopActivityLocked中启动Activity流程的差异。

此时的AMS场景是,Launcher已经启动,首次启动第三方进程Activity。第一阶段首先进入resumeTopActivityLocked方法分析

这里next对象即马上要启动的三方进程Activity,明显部位空,继续分析

这个场景下,焦点栈刚新建,此时prev对象为空,这个逻辑块不会进去,按序分析

在维护的stop及其它状态LIST中移除nest对象

这里注意下,mResumedActivity对象为空,另执行完pauseBackStacks后返回pausing状态为true,所以直接在这里返回。

第二阶段重点来看下pauseBackStacks方法

很明显,此时homeStack中mResumedActivity不为空,且此时homeStack不是焦点栈,因此要对非焦点栈执行pause动作,进入来分析

如上图代码显示,首先是对HomeStack中特殊Activity状态维护。同时又代码:

        prev.state = ActivityState.PAUSING;

        prev.task.touchActiveTime();

这里将prev(Launcher)的状态设置为PAUSING,达到对AMS中ActivityRecord的状态维护。一般而言在对应的用户进程中有对应对象,其状态也需要维护,后续会涉及

继续分析,这里通过prev对象持有的app属性成员,调用schedulePauseActivity方法,实现IPC通信。同步的这里要注意,通过mStackSupervisor.acquireLaunchWakelock()来申请wake锁,防止在Activity切换时,设备误进入休眠(earlySuspend)状态。

其中prev对象的appToken为IApplicationToken.Stub类型,是三方进程的Binder句柄。

通过上图可以看到prev.app.thread对象是IApplicationThread的proexy代理,其本体实现在三方进程内的ActivityThread(这里特制Launcher进程)。

最后一个阶段来看下此时ActivityThread内的交互

        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges) {
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0),
                    configChanges);
        }

如上面代码,在Activity中直接通过Handler来分发处理信息,此时的MsgID为PAUSE_ACTIVITY,继续来看下是如何处理此信息的

这里通过handlePauseActivity来处理,其中逻辑分为两步:

  1. 在ActivityThread中暂停对应的Activity
  2. 告知AMS暂停完成。

这里还需要关注下ActivityClientRecord类,这个类类似于AMS中ActivityRecord,在客户端进程内维护Activity信息。下面首先来看下在客户端进程(Launcher)如何暂停Activity,进入performPauseActivity方法:

这里通过mInstrumentation执行Activity的生命周期方法onPause().,同时维护ActivityClientRecord对象状态:

把paused属性变量设置为True,代表此Activity处于暂停状态。此时回到handlePauseActivity函数,通过

try {
       ActivityManagerNative.getDefault().activityPaused(token);
    } catch (RemoteException ex) {
}

activityPaused方法通知AMS,暂停Ativity结束,这里回到AMS来看下如何处理

根据这里分析的场景,此时Stack是HomeStack,此时通过stack的方法activityPausedLocked来通知对应Activity暂停结束,它通过调用completePauseLocked方法,完成通知,这里来看下completePauseLocked方法:

这里可以看到,首先找到topStack焦点栈,然后调用resumeTopActivitiesLocked开启二次寻租,此时的场景对应状态为,Launcher已经完成Pause,新开启的Activity只需启动了。

至此为止,已经分析完了首次启动普通客户端Activity与启动Launcher 流程间差异,下面基于此来总结下AMS在整个过程中的管理方式。

 

2.2 AMS管理过程

通过2.1的分析结合第一篇对AMS分析,这里来看下在首次启动Launcher及Activity过程中AMS的数据流。

在上面数据流图中,每个加工的TAG有:

AMS: ActivityManagerService

ASS: ActivityStackSupervisor

AS: ActivityStack

通过此数据流图,可以看到下面三点

  1. 对于不同的业务流程AMS管理框架通过统一的抽象过程(函数)来解决,另外
  2. ASS一般是对ActivityStack及ActivtyRecord的生成管理,AS负责具体栈内ActivityRecord群举管理,AMS则是对此过程涉及状态的统一维护
  3. 对于AS中的核心方法resumeTopActivityLocked,隐藏了核心细节。

 

3 Activity调度分析

基于第三方进程内Activity的启动,及回退流程,区别2.2节数据流图展示的统一流程,通过分析AS及ASS对Activity控制来展示差异化细节,更加全面的理解AMS的调度流程及细节。

3.1 进程内Activty启动

继续基于第二节分析,这里的用户场景是已经启动Launcher,及三方用户程序,且当前界面是三方进程内MainActivity。

此时在MainActivity内点击启动二级界面HelloWorld。基于2.2数据流图,重点关注 AS中的resumeTopActivityLocked的逻辑,在这之前的控制流程,参考日志:

开始分析之前,来看下下图的逻辑流程

同理,在启动二级Activity时,AMS通过两次resumeTopActivity来完成Activity的调度,这里忽略第一次resumeTopActivity逻辑,从第二次开始分析。进入resumeTopActivity有

这里prev是三方进程的一级Activity,此时非空,继续分析

这里mResumedActivity是空,通过第一轮的resumeTopActivity一级Activity完成了暂停,此时的mResumedActivity为空。

接下来判断prev不为空:

将prev对象添加到AMS中全局mWaitingVisibleActivities对象中,供后续逻辑处理,继续往下分析

此时next的app属性还是空,直接调用startSpecificActivityLocked来继续逻辑

mStackSupervisor.startSpecificActivityLocked(next, true, true);

进入startSpecificActivityLocked方法继续分析

 

已知此时一级界面已经启动完成,所以app对象非空,直接调用realStartActivityLocked来处理,在此方法中主要处理有

  1. 更新ActivityRecord属性状态值
  2. 更新ActivityRecord对应ProcessRecord在LRU队列位置
  3. 通知ActivityThread启动二级页面
  4. 其它

这里重点来分析第三点,进入realStartActivityLocked方法

此时通过Binder,由ActivityThread执行具体逻辑,进入ActivityThread来看

这个方法主要是依赖AMS传递过来的入参,在客户端进程中构建对应的ActivityClientRecord对象,之后发送Handler信息。

这里来看下如何处理LAUNCH_ACTIVITY信息

进入handleLaunchActivity方法来继续分析

这个函数主要做了两件事

  1. performLaunchActivity:新建并启动Activity
  2. handleResumeActivity:执行onresume方法

先来简单分析下performLaunchActivity方法

通过ClassLoader做入参,新建一个Activity对象,接下来通过attach来绑定对象新建窗口Window对象,这个后面会介绍到。

在handleResumeActivity方法,顾名思义,会执行Activity的onResume方法,然后通过下面代码将此二级Activity对应的Window绑定到系统服务WindowManagerService,以便于后期此二级界面接受输入事件

可以看到这里通过WindowManager来完成绑定,这里不展开,感兴趣可以自己查看相关代码。

此时基本完成了realStartActivityLocked中启动Activity逻辑分析,回到此函数,可以看到在完成上面动作后,有:

这两个函数基于AMS的管理框架,完成一些状态维护,这里由于篇幅所限不展开。

至此,基本简要分析完了二级Actiity的启动过程,AMS在Activity调度中基本依赖2.2描述的数据流图来管控,但是针对多场景Activity现状,AMS的控制会不同,细节聚焦在具体函数中,但万变不离其宗。

3.2 进程内Activity回退

基于3.1节场景,现在来分析下二级Activity界面的回退流程,此时AMS中栈状态为:

以上述AMS静态状态,Activity回退依赖于2.2分析的数据流图,这里从ActivityStackSupervisor类的startActivityUncheckedLocked方法做入口,此时已经依赖intent解析并新建ActivityRecord对象,入口如下:

同步对应的打印日志如下:

在上面的分析中,startActivityUncheckedLocked主要负责入参ActivtyRecord对应的stack及task的适配,这里在回退流程中有:

这里targetStack,根据当前AMS静态状态,其实就是当前的焦点Stack。然后将此task设置到入参activtyRecord中

继续分析,调用ActivityStack的startActivityLock方法,其中逻辑有:

在这里将ActivityRecord添加到task中,此时可以看到普通模式穹启动Activity,针对相同activty会新建ActivityRecord插入到task中,其后续启动模式已经类似二次启动Activity了。

对应到ActivityStack中的resumeTopActivityLocked方法,核心逻辑可以看到

在这里,pause此stack的resumeActivity,这个场景下就是HelloWorldActivity了。可以看到数据走向归属于AMS的数据流,逻辑走向类似二次启动Activity。

 

至此结束了Activity调度分析,通过AMS管理框架的类信息分析,AMS中Activity几个核心流程调度分析以及AMS数据流图分析,初步对AMS是如何管理Activity类信息,Activity生命周期流转有了基本的了解,对具体场景分析,有兴趣的可以在此基础上深入代码。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值