android 4.4的栈结构变化,Android 4.4的栈结构变化

我们知道,activity 在 AMS 中的形式是 ActivityRecord,task 在 AMS 中的形式为TaskRecord,进程在 AMS 中的管理形式为 ProcessRecord。

我们先看下 4.4 之前的版本:

android4.4 之前的版本,AMS 管理 Task 是通过一个 ArrayList mHistory 来管理所有的 activity:

0818b9ca8b590ca3270a3433284dd417.png

结论如下:

(1)所有的 ActivityRecord 会被存储在 mHistory 管理;

(2) 每个 ActivityRecord 会对应到一个 TaskRecord,并且有着相同 TaskRecord 的

ActivityRecord 在 mHistory 中会处在连续的位置;

(3)同一个 TaskRecord 的 Activity 可能分别处于不同的进程中,每个 Activity 所

处的进程跟 task 没有关系;

(4)TaskRecord 和 ProcessRecord 没有联系。

4.4 版本的管理方式发生了变化:

4.4

0818b9ca8b590ca3270a3433284dd417.png

4.2

0818b9ca8b590ca3270a3433284dd417.png

可以发现,4.4 新增了一个 ActivityStackSupervisor 类来辅助管理 TaskStack,查看源码可知:

/** The stack containing the launcher app */privateActivityStack mHomeStack;/** The non-home stack currently receiving input or launching the nextactivity. Ifhome is* in front then mHomeStack overrides mFocusedStack.* DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */privateActivityStack mFocusedStack;/** All the non-launcher stacks */privateArrayList mStacks =newArrayList();privatestaticfinalintSTACK_STATE_HOME_IN_FRONT =0;privatestaticfinalintSTACK_STATE_HOME_TO_BACK =1;privatestaticfinalintSTACK_STATE_HOME_IN_BACK =2;privatestaticfinalintSTACK_STATE_HOME_TO_FRONT =3;privateintmStackState = STACK_STATE_HOME_IN_FRONT;

从注释可以看出来,在 Android4.4 中,并不采用原先的 mHistory 来管理所有的Activity,而是按层次进行管理:

ActivityStackSupervisor 中 mStacks 中只包含了两个 Stack 就是 mHomeStack 和mFocusStack。mHomeStack 中只保存了 Launcher 的 Task,其他的 Task 则都放入

mFocusStack 中。对 Task 的操作,AMS 使用 mStackSupervisor 来进行。对于 Acitivity 的操作,AMS 使用 ActivityStack 来进行。

0818b9ca8b590ca3270a3433284dd417.png

结论如下:

(1)管理层次的最上面是一个 ActivityStack 类型的数组 mStacks,用于管理所有的 ActivityStack。

(2)系统中只有两个 ActivityStack,一个是 mHomeStack,用于保存 Launcher 的Activity,另一个是 mFocusedStack,用于保存非 Launcher 的 App 的 Activity。

ps:调查发现,长按 home 出现的任务管理界面 Recent 也会保存在 mHomeStack。

(3)mStacks 数组中,只有上述的两个栈,但不知道为什么要用一个 List 来管理这两个元素。

(4)在每个 ActivityStack 中,都可以拥有多个 TaskRecord。这些 TaskRecord 存储在 ActivityStack.java:ArrayList mTaskHistory 之中。

(5)在 TaskRecord 中,包含 ArrayList mActivities,用于存放该Task 中的所有的 Activity 的信息;包含 ActivityStack stack,用于记录所属的栈;包含 int

numActivities,用于记录当前 Task 中的 Activity 数量。

(6)综合上面的分析可知,要想找到某个 Activity,需要按层次查找:先找到对应的栈,再找到栈中的 Task,再在该 Task 中查找 Activity。

需要注意的是:

voidremoveTask(TaskRecord task) {mWindowManager.removeTask(task.taskId);finalActivityStack stack = task.stack;finalActivityRecord r = stack.mResumedActivity;if(r !=null&& r.task == task) {stack.mResumedActivity =null;}if(stack.removeTask(task) && !stack.isHomeStack()) {if(DEBUG_STACK) Slog.i(TAG,"removeTask: removing stack "+ stack);mStacks.remove(stack);finalintstackId = stack.mStackId;finalintnextStackId = mWindowManager.removeStack(stackId);// TODO: Perhaps we need to let the ActivityManager determine the next focus...if (mFocusedStack == null || mFocusedStack.mStackId == stackId) {// If this is the last app stack, set mFocusedStack to null.mFocusedStack = nextStackId == HOME_STACK_ID ? null :getStack(nextStackId);}}}ActivityStack getLastStack() {switch (mStackState) {case STACK_STATE_HOME_IN_FRONT:case STACK_STATE_HOME_TO_BACK:return mHomeStack;case STACK_STATE_HOME_TO_FRONT:case STACK_STATE_HOME_IN_BACK:default:return mFocusedStack;}} 源代码貌似是在这两个 stack 中来回切换,切换的时候会确定下一个FocusedStack,但是源码里面的一句注释// TODO: Perhaps we need to let the ActivityManager determine the next focus...比较让人匪夷所思。看来具体的如何取得下一个 focus 是在 AMS 中控制的。所以,开发者需要在 4.4 的开发中注意使用 android:launchMode="singleInstance"这 种启动模式,因为 4.4 下这种启动模式的调度方式与 4.2 有区别(区别原因应该在ActivityManager 中,具体原因还在调查中。。。),如果要使用的话一定要做好测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值