Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 4.4的棧結構變化

Android 4.4的棧結構變化

編輯:關於Android編程

我們知道,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 mStacks = new ArrayList();
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 mTaskHistory 之中。
(5)在 TaskRecord 中,包含 ArrayList 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 中,具體原因還在調查中。。。),如果要使用的話一定要做好測試。




  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved