Android 4.4堆叠结构的变化

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

        我们先看下 4.4 之前的版本号:
android4.4 之前的版本号,AMS 管理 Task 是通过一个 ArrayList mHistory 来管理全部的 activity:


结论例如以下:
(1)全部的 ActivityRecord 会被存储在 mHistory 管理;
(2) 每一个 ActivityRecord 会相应到一个 TaskRecord,而且有着同样 TaskRecord 的
ActivityRecord 在 mHistory 中会处在连续的位置;
(3)同一个 TaskRecord 的 Activity 可能分别处于不同的进程中,每一个 Activity 所
处的进程跟 task 没有关系;
(4)TaskRecord 和 ProcessRecord 没有联系。


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

4.4


4.2


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

/** The stack containing the launcher app */
private ActivityStack mHomeStack;
/** The non-home stack currently receiving input or launching the next
activity. If
home is
* in front then mHomeStack overrides mFocusedStack.
* DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
private ActivityStack mFocusedStack;
/** All the non-launcher stacks */
private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
private static final int STACK_STATE_HOME_IN_FRONT = 0;
private static final int STACK_STATE_HOME_TO_BACK = 1;
private static final int STACK_STATE_HOME_IN_BACK = 2;
private static final int STACK_STATE_HOME_TO_FRONT = 3;
private int mStackState = 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 来进行。


结论例如以下:
(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<TaskRecord> mTaskHistory 之中。
(5)在 TaskRecord 中,包括 ArrayList<ActivityRecord> mActivities,用于存放该Task 中的全部的 Activity 的信息;包括 ActivityStack stack,用于记录所属的栈;包括 int
numActivities,用于记录当前 Task 中的 Activity 数量。
(6)综合上面的分析可知,要想找到某个 Activity,须要按层次查找:先找到相应的栈,再找到栈中的 Task,再在该 Task 中查找 Activity。

须要注意的是:

void removeTask(TaskRecord task) {
mWindowManager.removeTask(task.taskId);
final ActivityStack stack = task.stack;
final ActivityRecord 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);
final int stackId = stack.mStackId;
final int nextStackId = 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 中,详细原因还在调查中。。。),假设要使用的话一定要做好測试。





版权声明:本文博客原创文章。博客,未经同意,不得转载。

posted @ 2015-07-17 18:23  mengfanrong  阅读(602)  评论(0编辑  收藏  举报