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 中,详细原因还在调查中。。。),假设要使用的话一定要做好測试。

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

时间: 2024-08-08 09:35:32

Android 4.4堆叠结构的变化的相关文章

Android系统源代码目录结构 “Android源代码”“目录结构”

在讲述Android源码编译的三个步骤之前,将先介绍Android源码目录结构,以便读者理清Android编译系统核心代码在Android源代码的位置. Android源代码顶层目录结构如下所示: ├──abi #应用二进制接口,不同的操作系统,应用二进制接口不同,因此linux上的二进制可执行文件在windows上无法执行 ├──android #存放了一些xml文件,用于描述工程路径及其对应的远程仓库地址,repo工具将使用这些信息同步代码 ├──bionic #bionic C库,Andr

【入门篇】Android学习笔记——项目结构及相关基础知识

Android项目具有其自身的结构规范,完好的遵循结构规范,可以让开发事半功倍.下图分别从Android视图和Project视图展示了Android项目的项目结构: 图中左侧是Android视图,右侧是Project视图.从两个结构图的对比,可以发现Android视图更加关注Android开发工作,而Project视图更加关注整体结构,虽然两个视图有一些不同,但主体结构并没有什么区别. 接下来,主要通过Android视图,描述一下Android项目中各个目录的用途和含义,明白Android视图中

Android系列教程之Android项目的目录结构

一: Android 项目的目录结构 Android 项目结构概览.其实 Android 项目的目录结构和 Java 的差不多,没有太大变化,如下图:  可以看到 src 文件夹里的是源文件, Android2.2 是引用的类库,这些和 java 的都一样,那么下面的这个 gen 是什么呢?这个里面的类就是 ADT 自动生成的啦,一般只有一个 R.java 文件,是不能修改的,那么他是怎么生成的呢,看到下面的 res 文件夹了吗? R.java 就是根据资源文件夹 res 生成的 ,R.java

Android 4.0 源代码结构

21.Android 4.0 源代码结构 Android源码的第一级目录结构 Android/abi (abi相关代码.ABI:application binary interface,应用程序二进制接口) Android/bionic(bionic C库) Android/bootable(启动引导相关代码) Android/build(存放系统编译规则及generic等基础开发配置包) Android/cts(Android兼容性测试套件标准) Android/dalvik(dalvik J

android项目的目录结构讲解

参考书籍:<第一行代码Android> 一:android项目的目录结构讲解 1..gradle和.idea ? ??? ? 这两个目录下放置的都是Android Studio自动生成的一些文件,我们无须关心,也不要去手动编辑. 2.app ? ??? ? 项目中的代码.资源等内容几乎都是放置在这个目录下的,我们后面的开发工作也基本都是在这个目录下进行的,待会儿还会对这个目录单独展开进行讲解. 3.build ? ??? ? 这个目录你也不需要过多关心,它主要包含了一些在编译时自动生成的文件.

处理Android程序运行时的配置变化

本篇文章翻译自Android官方文档Handling Runtime Changes,有翻译错误请留言告知,多谢. Android程序在运行期间设备的配置是可能发生改变的(例如屏幕的方向,键盘可用性,和语言等).当这些配置发生变化时,Android会重启正在运行的Activity(先调用onDestory(),紧接着调用onCreate()).这个设计是为了让你的程序在配置发生变化时,使用不同的资源自动去适配新的配置机器. 正确的处理重启,一件很重要的事就是通过Activity正常的生命周期去恢

Android无限级树状结构

通过对ListView简单的扩展.再封装,即可实现无限层级的树控件TreeView. 1 package cn.asiontang.nleveltreelistview; 2 3 import android.annotation.TargetApi; 4 import android.content.Context; 5 import android.os.Build; 6 import android.util.AttributeSet; 7 import android.view.View

Android Wear - App Structure for Android Wear(应用结构)

原文地址:http://developer.android.com/design/wear/structure.html 用户习惯于点击图标来启动应用程序,但是Android Wear不一样.一个典型的Wear应用程序会在一个情境的合适时刻插入一张卡片到信息流中.这张卡片可能会包含一个用于快速交互的按钮来打开一个全屏视图(在一些情况下,卡片也可能不会提供交互按钮): 以下是简单排序的构建模块.你可以使用其中的一个或者多个模块,但是我们强烈推荐不要构建这样的应用:用户在启动或者退出应用之前必须仔细

Android 5.0 源代码结构

本节书摘来自异步社区<深入理解Android 5 源代码>一书中的第2章,第2.2节分析Android源代码结构,作者 李骏. 网址:https://yq.aliyun.com/articles/93279?spm=5176.100239.blogcont93310.17.gtBsUg 2.2 分析Android源代码结构 获得Android 5.0源代码后,源代码的全部工程分为以下3个部分. Core Project:核心工程部分,这是建立Android系统的基础,被保存在根目录的各个文件夹