前言:最近一直在看关于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.
*/finalclassActivityRecord{finalComponentName realActivity;// the intent component, or target of an alias.finalString shortComponentName;// the short component name of the intentfinalString packageName;// the package implementing intent's componentfinalString processName;// process where this component wants to runfinalString taskAffinity;// as per ActivityInfo.taskAffinityboolean fullscreen;// covers the full screen?}
TaskRecord
TaskRecord表示任务栈,用于记录activity开启的先后顺序。其所存放的Activity是不支持重新排序的,只能根据压栈和出栈操作更改Activity的顺序。有了TaskRecord,Android系统才能知道当一个Activity退出时,接下来该显示哪一个Activity。
finalclassTaskRecord{/** List of all activities in the task arranged in history order */finalArrayList<ActivityRecord>mActivities;}
ActivityStack
ActivityStack这个类在名字上给人很大的误解,Stack是栈的意思(Heap是堆的意思),那ActivityStack就表示“Activity的栈”?其实不是。从下面的代码中可以看出ActivityStack维护的是TaskRecord的列表。而且该列表也不是栈结构,列表中的TaskRecord可以重排顺序。
finalclassActivityStack{/**
* The back history of all previous (and possibly still
* running) activities. It contains #TaskRecord objects.
*/privateArrayList<TaskRecord>mTaskHistory=newArrayList<>();}
ActivityDisplay
ActivityDisplay表示一个屏幕,Android支持三种屏幕:主屏幕,外接屏幕(HDMI等),虚拟屏幕(投屏)。一般情况下,即只有主屏幕时,ActivityStackSupervisor与ActivityDisplay都是系统唯一。
ActivityDisplay是ActivityStackSupervisor的内部类,它相当于一个工具类,封装了移除和添加ActivityStack的方法。
classActivityDisplay{final ArrayList<ActivityStack>mStacks=newArrayList<ActivityStack>();voidattachActivities(ActivityStack stack){if(DEBUG_STACK)Slog.v(TAG_STACK,"attachActivities: attaching "+stack+" to displayId="+mDisplayId);mStacks.add(stack);}voiddetachActivitiesLocked(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栈。
publicfinalclassActivityStackSupervisorimplementsDisplayListener{/** The stack containing the launcher app. Assumed to always be attached to
* Display.DEFAULT_DISPLAY. */privateActivityStackmHomeStack;/** The stack currently receiving input or launching the next activity. */privateActivityStackmFocusedStack;/** 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. */privateActivityStackmLastFocusedStack;/** Mapping from (ActivityStack/TaskStack).mStackId to their current state */privateSparseArray<ActivityContainer>mActivityContainers=newSparseArray<>();ActivityStackcreateStackOnDisplay(intstackId,intdisplayId){……ActivityContaineractivityContainer=newActivityContainer(stackId);mActivityContainers.put(stackId,activityContainer);activityContainer.attachToDisplayLocked(activityDisplay);returnactivityContainer.mStack;}classActivityContainerextendsandroid.app.IActivityContainer.Stub{finalActivityStackmStack;ActivityDisplaymActivityDisplay;ActivityContainer(intstackId){synchronized(mService){mStackId=stackId;mStack=newActivityStack(this,mRecentTasks);}}voidattachToDisplayLocked(ActivityDisplayactivityDisplay){…… mActivityDisplay=activityDisplay;activityDisplay.attachActivities(mStack);}protectedvoiddetachLocked(){……if(mActivityDisplay!=null){mActivityDisplay.detachActivitiesLocked(mStack);}}}}
ActivityDisplay的添加和移除ActivityStack的方法又被封装进了ActivityContainer类中,ActivityStackSupervisor调用ActivityContainer的attachToDisplayLocked与detachLocked对ActivityStack列表进行重排序,将任务栈从后台切换至前台。
前台任务栈与后台任务栈
如上图所示,只有Task #5才是前台任务栈,其余的都是后台任务栈。后台任务栈里面的Activity全部处于onStop状态。
网友评论