本文主要从3个方面来介绍这ActivityDisplay/ActivityStack/TaskRecord/ActivityRecord的关系几个类之间的关系,先从整体关系图,对4个类的关系有个大概的了解,然后通过dumpsys命令,来验证这种关系;然后从类定义的角度来看,4个类是如何互相包含的;最后从Activity启动的流程过程来看4个类是如何关联上来的。
通过阅读本文,能对ActivityDisplay/ActivityStack/TaskRecord/ActivityRecord的关系有个整体的认识和理解
1.整体关系图如下
通过adb shell dumpsys activity activities 命令可以看到如下打印:
说明:
1.在#0的ActivityDisplay上,总共有2个Stack,代表2个应用
2.在Stack #4里面,有一个TaskRecord,Task id #87
3.在TaskRecord里面,Activities列表里面只有一个ActivityRecord
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
Stack #4: type=standard mode=fullscreen
isSleeping=false
mBounds=Rect(0, 0 - 0, 0)
Task id #87
* TaskRecord{3a93f6f #87 A=com.android.deskclock U=0 StackId=4 sz=1}
userId=0 effectiveUid=u0a93 mCallingUid=u0a81 mUserSetupComplete=true mCallingPackage=com.android.launcher3
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.deskclock/.DeskClock}
Activities=[ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87}]
mRootProcess=ProcessRecord{64a3d2f 4887:com.android.deskclock/u0a93}
stackId=4
hasBeenVisible=true mResizeMode=RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION mSupportsPictureInPicture=false isResizeable=true lastActiveTime=223590378 (inactive for 50s)
* Hist #0: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87}
app=ProcessRecord{64a3d2f 4887:com.android.deskclock/u0a93}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.deskclock/.DeskClock bnds=[35,503][237,780] }
state=RESUMED stopped=false delayedResume=false finishing=false
Running activities (most recent first):
TaskRecord{3a93f6f #87 A=com.android.deskclock U=0 StackId=4 sz=1}
Run #0: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87}
mResumedActivity: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87}
mLastPausedActivity: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87}
Stack #0: type=home mode=fullscreen
isSleeping=false
mBounds=Rect(0, 0 - 0, 0)
Task id #83
mBounds=Rect(0, 0 - 0, 0)
mMinWidth=-1
mMinHeight=-1
mLastNonFullscreenBounds=null
* TaskRecord{6dee666 #83 ?? U=0 StackId=0 sz=1}
userId=0 effectiveUid=u0a81 mCallingUid=u0a81 mUserSetupComplete=true mCallingPackage=com.android.launcher3
intent={act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.launcher3/.Launcher}
Activities=[ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83}]
mRootProcess=ProcessRecord{d9a8f3c 2055:com.android.launcher3/u0a81}
stackId=0
hasBeenVisible=true mResizeMode=RESIZE_MODE_RESIZEABLE mSupportsPictureInPicture=false isResizeable=true lastActiveTime=223589976 (inactive for 50s)
* Hist #0: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83}
app=ProcessRecord{d9a8f3c 2055:com.android.launcher3/u0a81}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.launcher3/.Launcher }
state=STOPPED stopped=true delayedResume=false finishing=false
Running activities (most recent first):
TaskRecord{6dee666 #83 ?? U=0 StackId=0 sz=1}
Run #0: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83}
mLastPausedActivity: ActivityRecord{3e98fcb u0 com.android.launcher3/.Launcher t83}
ResumedActivity:ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87}
ResumedActivity: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t87}
2.类定义相关介绍
整体类图如下:
2.1 ActivityDisplay
ActivityDisplay 类有如下关键变量
DisplayContent mDisplayContent; // 对应WindowManagerService的显示
/** Actual Display this object tracks. */
int mDisplayId; // id
/**
* All of the stacks on this display. Order matters, topmost stack is in front of all other
* stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls
* changing the list should also call {@link #onStackOrderChanged()}.
*/
// 当前显示屏上的所有ActivityStack
private final ArrayList<ActivityStack> mStacks = new ArrayList<>();
2.2 ActivityStack
ActivityStack类有如下关键变量
final int mStackId; // 唯一ID
/** The attached Display's unique identifier, or -1 if detached */
int mDisplayId; // 所处的显示屏id,如果detach则为-1
/**
* The back history of all previous (and possibly still
* running) activities. It contains #TaskRecord objects.
*/
// ActivityStack里面所包含的所有TaskRecord对象
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
TaskStack mTaskStack; // 对应WindowManagerService里面的
/**
* Current activity that is resumed, or null if there is none.
*/
ActivityRecord mResumedActivity = null; // 当前resume状态的Activity
2.3 TaskRecord
TaskRecord 类有如下关键变量
final int taskId; // Unique identifier for this task.
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities; // 当前Task里面所包含的所有Activity对象
/** Current stack. Setter must always be used to update the value. */
private ActivityStack mStack; // 所属的ActivityStack
Task mTask; // 对应WindowManagerService里面的
2.4 ActivityRecord
ActivityRecord 类有如下关键变量
final IApplicationToken.Stub appToken; // window manager token
// TODO: Remove after unification
AppWindowToken mAppWindowToken; // 继承自WindowToken,代表一种window类型,为应用窗口
// activity相关的信息
final ActivityInfo info; // all about me
private TaskRecord task; // the task this is in.
// ActivityRecord在初始化的时候会创建Token对象,作为服务端
static class Token extends IApplicationToken.Stub
3.ActivityDisplay/ActivityStack/TaskRecord/ActivityRecord如何关联
详细流程可以阅读Activity 启动流程log分析
3.1 ActivityRecord创建
在startActivity的过程中,会先new ActivityRecord
08-23 17:30:21.261 1314 4528 V ActivityTaskManager: java.lang.Throwable
08-23 17:30:21.261 1314 4528 V ActivityTaskManager: at com.android.server.wm.ActivityRecord.setState(ActivityRecord.java:1857)
08-23 17:30:21.261 1314 4528 V ActivityTaskManager: at com.android.server.wm.ActivityRecord.<init>(ActivityRecord.java:964)
08-23 17:30:21.261 1314 4528 V ActivityTaskManager: at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:902)
3.2 ActivityStack创建以及和ActivityDisplay的关联
ActivityStack也在是startActivity的过程中创建的
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStack.<init>(ActivityStack.java:511)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityDisplay.createStackUnchecked(ActivityDisplay.java:465)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityDisplay.createStack(ActivityDisplay.java:455)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityDisplay.getOrCreateStack(ActivityDisplay.java:383)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityDisplay.getOrCreateStack(ActivityDisplay.java:401)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.RootActivityContainer.getLaunchStack(RootActivityContainer.java:1737)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.getLaunchStack(ActivityStarter.java:2704)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.computeStackFocus(ActivityStarter.java:2612)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.setTaskFromReuseOrCreateNewTask(ActivityStarter.java:2323)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1688)
08-23 17:30:21.285 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:1404)
在ActivityStack的构造方法中,会调用ActivityDisplay的addChild方法,
display.addChild(this, onTop ? POSITION_TOP : POSITION_BOTTOM);
将自己加入到ActivityDisplay的mStack里面,mStack定义如下
ArrayList<ActivityStack> mStacks
此时,ActivityDisplay和ActivityStack关联起来
3.3 TaskRecord创建以及和ActivityStack的关联
TaskRecord也在是startActivity的过程中创建的
08-23 17:30:21.292 1314 4528 D ActivityTaskManager: at com.android.server.wm.TaskRecord.create(TaskRecord.java:2704)
08-23 17:30:21.292 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStack.createTaskRecord(ActivityStack.java:5515)
08-23 17:30:21.292 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.setTaskFromReuseOrCreateNewTask(ActivityStarter.java:2330)
08-23 17:30:21.292 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1688)
在ActivityStack.createTaskRecord方法里面,调用addTask将TaskRecord和ActivityStack关联起来
addTask(task, toTop, "createTaskRecord");
将task加入 mTaskHistory,其定义如下
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
3.4 TaskRecord和ActivityRecord的关联
在3.1 和3.3节分别创建了ActivityRecord和TaskRecord对象,
08-23 17:30:21.296 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:2574)
08-23 17:30:21.296 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.setTaskFromReuseOrCreateNewTask(ActivityStarter.java:2335)
08-23 17:30:21.296 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1688)
08-23 17:30:21.296 1314 4528 D ActivityTaskManager: at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:1404)
在setTaskFromReuseOrCreateNewTask方法里面,先调用createTaskRecord来创建TaskRecord,然后调用addOrReparentStartingActivity来设置Activity与TaskRecord的关系
setTaskFromReuseOrCreateNewTask () {
.....
final TaskRecord task = mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
.....
}
private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Slog.d(TAG,"addOrReparentStartingActivity",new Throwable());
// 如果当前ActivityRecord没有设置TaskRecord或者已经设置过就是给定的parent,则添加到mActivities列表里面
if (mStartActivity.getTaskRecord() == null || mStartActivity.getTaskRecord() == parent) {
parent.addActivityToTop(mStartActivity); // 会调用r.setTask(this)设置关联关系
} else {
// 将当前要启动的Activity重新关联到给定的parent 上
mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
}
}
————————————————
版权声明:本文为CSDN博主「chadm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42695485/article/details/108680240