前言:最近一直在看关于Activity的文章,刚好郭神推了这篇文章,以前一直没关注过这几个概念,今天学习一下。
提问:ActivityRecord、TaskRecord、ActivityStack、ActivityDisplay、ActivityStackSupervisor。它们是什么?可以用来干什么?以及怎么干的?
常规回答:ActivityStackSupervisor管理ActivityDisplay,ActivityDisplay管理ActivityStack、ActivityStack管理TaskRecord、TaskRecord管理ActivityRecord。
ActivityRecord
ActivityRecord是Activity在system_server进程中的镜像,Activity实例与ActivityRecord实例一一对应。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是栈的意思(Heap是堆的意思),那ActivityStack就表示“Activity的栈”?其实不是。从下面的代码中可以看出ActivityStack维护的是TaskRecord的列表。而且该列表也不是栈结构,列表中的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<>();
}
ActivityDisplay
ActivityDisplay表示一个屏幕,Android支持三种屏幕:主屏幕,外接屏幕(HDMI等),虚拟屏幕(投屏)。一般情况下,即只有主屏幕时,ActivityStackSupervisor与ActivityDisplay都是系统唯一。
ActivityDisplay是ActivityStackSupervisor的内部类,它相当于一个工具类,封装了移除和添加ActivityStack的方法。
class ActivityDisplay {
final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
void attachActivities(ActivityStack stack) {
if (DEBUG_STACK) Slog.v(TAG_STACK,
"attachActivities: attaching " + stack + " to displayId=" + mDisplayId);
mStacks.add(stack);
}
void detachActivitiesLocked(ActivityStack stack) {
if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack
+ " from displayId=" + mDisplayId);
mStacks.remove(stack);
}
}
ActivityStackSupervisor
ActivityStackSupervisor是ActivityStack的管理者,内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个ActivityStack。其中,mHomeStack管理的是Launcher相关的Activity栈, stackId为0;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
public final class ActivityStackSupervisor implements DisplayListener {
/** The stack containing the launcher app. Assumed to always be attached to
* Display.DEFAULT_DISPLAY. */
private ActivityStack mHomeStack;
/** The stack currently receiving input or launching the next activity. */
private ActivityStack mFocusedStack;
/** If this is the same as mFocusedStack then the activity on the top of the focused stack has
* been resumed. If stacks are changing position this will hold the old stack until the new
* stack becomes resumed after which it will be set to mFocusedStack. */
private ActivityStack mLastFocusedStack;
/** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>();
ActivityStack createStackOnDisplay(int stackId, int displayId) {
……
ActivityContainer activityContainer = new ActivityContainer(stackId);
mActivityContainers.put(stackId, activityContainer);
activityContainer.attachToDisplayLocked(activityDisplay);
return activityContainer.mStack;
}
class ActivityContainer extends android.app.IActivityContainer.Stub {
final ActivityStack mStack;
ActivityDisplay mActivityDisplay;
ActivityContainer(int stackId) {
synchronized (mService) {
mStackId = stackId;
mStack = new ActivityStack(this, mRecentTasks);
}
}
void attachToDisplayLocked(ActivityDisplay activityDisplay) {
……
mActivityDisplay = activityDisplay;
activityDisplay.attachActivities(mStack);
}
protected void detachLocked() {
……
if (mActivityDisplay != null) {
mActivityDisplay.detachActivitiesLocked(mStack);
}
}
}
}
ActivityDisplay的添加和移除ActivityStack的方法又被封装进了ActivityContainer类中,ActivityStackSupervisor调用ActivityContainer的attachToDisplayLocked与detachLocked对ActivityStack列表进行重排序,将任务栈从后台切换至前台。
前台任务栈与后台任务栈
如上图所示,只有Task #5才是前台任务栈,其余的都是后台任务栈。后台任务栈里面的Activity全部处于onStop状态。
最后:原文里面还有对一个APP对应一个ActivityStack
的验证,感兴趣的可以去原文查看
申明:开始和结束的图片来源网络,侵删
网友评论