美文网首页AMS
ActivityRecord、TaskRecord、Activi

ActivityRecord、TaskRecord、Activi

作者: JunL_Dev | 来源:发表于2019-10-30 16:05 被阅读0次
    Start

    前言:最近一直在看关于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的验证,感兴趣的可以去原文查看

    郭霖转发地址
    原作者地址

    申明:开始和结束的图片来源网络,侵删

    End

    相关文章

      网友评论

        本文标题:ActivityRecord、TaskRecord、Activi

        本文链接:https://www.haomeiwen.com/subject/gbdovctx.html