最近在阅读Activity启动过程时接触到了这几个概念:ActivityRecord、TaskRecord、ActivityStack、ActivityDisplay、ActivityStackSupervisor
。它们是什么,可以用来干什么,以及怎么干的。网络上没有几篇文章可以说明白的,常见的回答就是ActivityStackSupervisor管理ActivityDisplay,ActivityDisplay管理ActivityStack、ActivityStack管理TaskRecord、TaskRecord管理ActivityRecord。但是到底怎么管理的?为什么要管理啊?哎,没讲明白~~。
今天就由我来介绍下这几个概念。
ActivityRecord
ActivityRecord
是Activity在system_server进程中的镜像,一个Activity实例就对应着一个ActivityRecord实例。它用来存储Activity的信息,如所在的进程名称,应用的包名,所在的任务栈的taskAffinity
等。
/**
* An entry in the history stack, representing an activity.
*/
final class ActivityRecord {
final ComponentName realActivity; // the intent component, or target of an alias.
final String shortComponentName; // the short component name of the intent
final String packageName; // the package implementing intent's component
final String processName; // process where this component wants to run
final String taskAffinity; // as per ActivityInfo.taskAffinity
boolean fullscreen; // covers the full screen?
}
TaskRecord
TaskRecord
表示任务栈,用于记录activity开启的先后顺序。其所存放的Activity是不支持重新排序的,只能根据压栈和出栈操作更改Activity的顺序。有了TaskRecord,Android系统才能知道当一个Activity退出时,接下来该显示哪一个Activity。
final class TaskRecord {
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities;
}
ActivityStack
ActivityStack
这个类在名字上给人很大的误解,Stack
是栈的意思,那ActivityStack
就表示“Activity的栈”?其实不是。从下面的代码中可以看出ActivityStack
维护的是TaskRecord的列表。
final class ActivityStack {
/**
* The back history of all previous (and possibly still
* running) activities. It contains #TaskRecord objects.
*/
private ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
}
也有人说是一个应用一个ActivityStack
。其实也不是。接下来就用命令行——adb shell dumpsys activity
,来验证下。
先准备2个APP。app1和app2各自都有两个页面,各自的启动页都是普通常见的,然后各自的都有另外一个其他页面,这分属于两个app的其他页面我们都给他们指定同一个任务栈名(这个任务栈名不跟任意一个app包名相同)。
也就是说app1里面有MainActivity和OtherActivity1。app2里面有MainActivity和OtherActivity2。两个应用的MainActivity都是普通的Standard启动模式,而OtherActivity1和OtherActivity2都在清单文件指定了同一个自定义的任务栈名称和singelTask启动模式。
我们这样操作:
第一阶段:先打开app1,再打开OtherActivity1页面,接着按下home键。
第二阶段:(接按下home件之后)打开app2,打开app2的OtherActivity2页面。
先贴上相关图片和代码:
app1的manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.a_task.application">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.a_task.application.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.a_task.application.OtherActivity1"
android:launchMode="singleTask"
android:taskAffinity="com.task.other.independent"/>
<activity android:name="com.a_task.application.StandActivity" />
</application>
</manifest>
app2的manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.b_task.application2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.b_task.application2.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.b_task.application2.OtherActivity2"
android:launchMode="singleTask"
android:taskAffinity="com.task.other.independent"/>
</application>
</manifest>
- 第一阶段:先打开app1,再打开OtherActivity1页面,接着按下home键。
在cmd窗口中输入adb shell dumpsys activity
。查看任务栈信息。搜索ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)部分的内容。
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
Stack #1:
Task id #18
TaskRecord{35556de #18 A=com.task.other.independent U=0 sz=1}
Hist #0: ActivityRecord{1aac911c u0 com.a_task.application/.OtherActivity1 t18}
Task id #17
TaskRecord{3981d0bf #17 A=com.a_task.application U=0 sz=1}
Hist #0: ActivityRecord{31a500b5 u0 com.a_task.application/.MainActivity t17}
Running activities (most recent first):
TaskRecord{35556de #18 A=com.task.other.independent U=0 sz=1}
Run #1: ActivityRecord{1aac911c u0 com.a_task.application/.OtherActivity1 t18}
TaskRecord{3981d0bf #17 A=com.a_task.application U=0 sz=1}
Run #0: ActivityRecord{31a500b5 u0 com.a_task.application/.MainActivity t17}
mResumedActivity: ActivityRecord{1aac911c u0 com.a_task.application/.OtherActivity1 t18}
Stack #0:
Task id #1
TaskRecord{3c9a438c #1 A=com.android.launcher3 U=0 sz=1}
Hist #0: ActivityRecord{91e63b0 u0 com.android.launcher3/.Launcher t1}
Running activities (most recent first):
TaskRecord{3c9a438c #1 A=com.android.launcher3 U=0 sz=1}
Run #0: ActivityRecord{91e63b0 u0 com.android.launcher3/.Launcher t1}