分享一个困惑很久的问题:App前台,Activity会被回收吗?
如果大家看得非常仔细,会看到在讲解 framework 相关代码的时候,出现了一堆关键类,例如:
-
ActivityRecord
-
TaskRecord
-
ActivityStack
-
ActivityDisplay
-
ActivityStackSupervisor
这些名字看起来感觉都有一定的含义,但是仔细想又没法完全说上来。
于是,我在 wanandroid 上更新了一个每日一问:
ActivityRecord、TaskRecord、ActivityStack、ActivityDisplay、ActivityStackSupervisor
-
这些类分别起到什么作用?
-
有什么好的方式帮助记忆吗?
以下为彭小铭同学的回答,非常感谢。
ActivityManagerService Activity栈管理
ActivityRecord
记录Activity的信息,并通过成员变量task指向TaskRecord。
类型 | 名称 | 说明 |
---|---|---|
ProcessRecord | app | 跑在哪个进程 |
TaskRecord | task | 跑在哪个task |
ActivityInfo | info | Activity信息 |
int | mActivityType | Activity类型 |
ActivityState | state | Activity状态 |
ApplicationInfo | appInfo | 跑在哪个app |
ComponentName | realActivity | 组件名 |
String | packageName | 包名 |
String | processName | 进程名 |
int | launchMode | 启动模式 |
int | userId | 该Activity运行在哪个用户Id |
TaskRecord
描述Activity的Affinity所属的栈。
类型 | 名称 | 说明 |
---|---|---|
ActivityStack | stack | 当前所属的stack |
ArrayList\<ActivityRecord\> | mActivities | 当前task的所有Activity列表 |
int | taskId | TaskRecord的Id |
String | affinity | root activity的affinity,即该Task中第一个Activity |
int | mCallingUid | 调用者的UserId |
String | mCallingPackage | 调用者的包名 |
ActivityStack
管理着TaskRecord,内部维护Activity所有状态、特殊状态的Activity和Activity相关的列表数据。
类型 | 名称 | 说明 |
---|---|---|
ArrayList\<TaskRecord\> | mTaskHistory | 保存所有的Task列表 |
ArrayList\<ActivityStack\> | mStacks | 所有的stack列表 |
int | mStackId | ActivityStackvisor的mActivityContainers的key值Id |
int | mDisplayId | ActivityStackSupervisor的mActivityDisplays的key值Id |
ActivityRecord | mPauseingActivity | 正在暂停的Activity |
ActivityRecord | mLastPausedActivity | 上一个已暂停的Activity |
ActivityRecord | mResumedActivity | 已经Resumed的Activity |
ActivityRecord | mLastStartedActivity | 最近一次启动的Activity |
ActivityStackSupervisor
管理所有的ActivityStack。
类型 | 名称 | 说明 |
---|---|---|
ActivityStack | mHomeStack | 桌面的stack |
ActivityStack | mFocusedStack | 当前聚焦的stack |
ActivityStack | mLastFocusedStack | 正在切换到聚焦的stack |
SparseArray\<ActivityDisplay\> | mActivityDisplays | displayId为key |
SparseArray\<ActivityContainer\> | mActivityContainers | mStackId为key |
ActivityDisplay
表示一个屏幕,Android支持三种屏幕:主屏幕,外接屏幕(HDMI等),虚拟屏幕(投屏)一般地,对于没有分屏功能以及虚拟屏的情况下,ActivityStackSupervisor与ActivityDisplay都是系统唯一;ActivityDisplay主要有Home Stack和App Stack这两个栈。
记忆关系链
每个ActivityStack中可以有若干个TaskRecord对象;每个TaskRecord中可以有若干个ActivityRecord对象;每个ActivityRecord记录一个Activity信息。
正向关系链表:
ActivityStackSupervisor.mActivityDisplays
-> ActivityDisplay.mStack
-> ActivityStack.mTaskHistory
-> TaskRecord.mActivities
-> ActivityRecord
反向关系链
ActivityRecord.task
-> TaskRecord.mStack
-> ActivityStack.mStackSupervisor
-> ActivityStackSupervisor
ActivityStack.mDisplayId可以找到对应的ActivityDisplay,HOME_STACK_ID=0可以在ActivityStackSupervisor.mActivityDisplays找到桌面的ActivityStack。
送个配图:
当然了不同的 framework 版本可能有所差异,不过影响不大,主要是自己要能理解和记住大概。
好了,结束,欢迎大家关注 wanandroid 每日一问,将持续给大家带来奇奇怪怪的问题扩展大家知识广度。
转自:
奇怪的知识:ActivityRecord、TaskRecord、ActivityStack、ActivityDisplay用处?
https://mp.weixin.qq.com/s/wRy216rcr0Ibu21zLNjSjQ