关闭

----------待修改-----------

221人阅读 评论(0) 收藏 举报
分类:

本文正在修正,补充当中。


理解AMS中对Activity管理、组织及切换的方式

本文的分析是基于Android 5.0.0 Google原生代码的。


ActivityMangerService这一系统级的服务,涉及到众多的数据结构。而建立这些数据结构的目的,在于有效的组织管理系统中运行的Activity。

相对于Android 4.0及此前的版本,Android 5.0之后Activity和ams之间交互和相关的数据结构关系改变了不少。

数据结构从低层次到高层次表现为:

ActivityRecord --> TaskRecord --> ActivityStack --> ActivityStackSupervisor

因此,要正确地理解AMS中对Activity管理、组织及切换的方式,我们也要熟悉AMS内部stack切换和task切换流程。

ActivityRecord代表一个最小的功能模块的记录者,也就是Activity的记录者。TaskRecord则是由一系列的最小功能模块组成,形成一个逻辑上的应用。

ActvityStackSupervisor顾名思议,是对ActvityStack进行管理的一个类。


为了让理解的思路更加清晰,我把本文的内容,从上至下,归纳为解决以下四个问题的过程:

1. ActivityStackSupervisor是如何管理ActivityStack的?

2. ActivityStack是如何管理TaskRecord的?

3. TaskRecord是如何管理ActivityRecord的?

4. Activity的生命周期,即Activity.onResume, onPause, onStop等方法是何时调用的?


接下来,我将结合源码及相关的重要函数,对这些问题逐个击破。

一、ActivityStackSupervisor分析

ActivityStackSupervisor管理着两个重要的ActivityStack。其定义如下:

    /** 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;

这两个成员变量定义在文件frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java当中。

ActivityStackSupervisor中mStacks中只包含了两个Stack就是mHomeStack和mFocusStack。

//错误观点!!:mHomeStack中只保存了Launcher的Task,其他的Task则都放入mFocusStack中。通过这两个变量的注释也能看出来。

(1) ActivityStackSupervisor.moveHomeStack()

    void moveHomeStack(boolean toFront) {
        //①
        ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
        int topNdx = stacks.size() - 1;
        if (topNdx <= 0) {
            return;
        }
        ActivityStack topStack = stacks.get(topNdx);
        final boolean homeInFront = topStack == mHomeStack;
        //②
        if (homeInFront != toFront) {
            mLastFocusedStack = topStack;
            //先remove再插入 保证mHomeStack始终处于mStacks中正确的位置
            stacks.remove(mHomeStack);         
            //如果toFront为true,就把mHomeStack放在顶层位置
            stacks.add(toFront ? topNdx : 0, mHomeStack);
            mFocusedStack = stacks.get(topNdx);
            if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
                    + mFocusedStack);
        }
    }

任意时刻,展现在用户眼前最前面的只有一个ActivityStack(最顶层的可见Activity必定属于且仅属于某一特定的ActivityStack),要么是mHomeStack,要么是mFocusedStack,我们称这个栈为前台栈(FrontStack)。从以下这个方法可以看出,FrontStack就是目前系统中所有ActivityStack里面最顶层的一个Stack。

    boolean isFrontStack(ActivityStack stack) {
        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
        if (parent != null) {
            stack = parent.task.stack;
        }
        ArrayList<ActivityStack> stacks = stack.mStacks;
        if (stacks != null && !stacks.isEmpty()) {
            //若stacks不为空,则判断当前的传入参数stack是否最顶层的一个ActivityStack
            return stack == stacks.get(stacks.size() - 1);
        }
        return false;
    }

该方法位于同一文件frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java当中。

当FrontStack在mHomeStack和mFocusedStack之间发生切换时,就会调用这个方法。 比如说:

例子1:在设置界面中按home键返回Launcher界面。

例子2:从Launcher界面点应用图标打开第三方的APP。

都会调用ActivityStackSupervisor.moveHomeStack()方法。

---------------------------------------------------------------------------------------------------------------------

ActivityStackSupervisor.moveHomeStack()需要注意的地方:

①在安卓4.4版本中,ActivityStackSupervisor有一个类型为ArrayList<ActivityStack>的mStacks成员变量,但其实只存放了两个ActivityStack——就是以上所提到的mHomeStack,mFocusedStack。 但是在安卓5.0.0及之后的版本,Google将这一成员变量移到了ActivityStack.java中。因此便出现了①中这样的语句:

ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
实际上,在目前的安卓的系统中,mHomeStack.mStacks和mFocused.mStacks的值是一样的。都会返回一个元素个数为2的,只存放了mHomeStack和mFocusedStack的ArrayList<ActivityStack>类型变量。在isFrontStack()方法中也能体现出这一点,无论传入什么stack,都会访问stack.mStacks这个ArrayList。

至于Google为什么这么做,应该是为了之后拓展和优化mFocusedStack这一ActivityStack结构,拆分出mHomeStack以外的多个ActivityStack,根据当前运行情况将其中的一个设置为mFocusedStack,从而更高效,健全地维护Activity的堆栈结构。毕竟现在除Laucher、RecentActivity这两个应用以外,所有的其他Task都放在mFocusedStack当中了。更甚,从当前版本Google对一些AMS这一大模块的函数和变量的注释,多少都可以看出来点端倪。当然,这只是我的个人看法。若大家批评指正,或者Google做了官方说明后,我会再做修正。

②homeInfront代表mHomeStack是否已经在前台,toFront参数决定是否要将mHomeStack移到前台。结合上面提到的两个例子解释:

例子1:toFront为true,因为此时要将Launcher所在的mHomeStack切换为FrontStack。

例子2:toFront为false,此时是要将mHomeStack移动到后台。

当且仅当homeInfront != toFront的时候,即mHomeStack当前的状态和要切换为的状态不同时才会进入之后的逻辑。


(2) ActivityStackSupervisor.resumeHomeStackTask()

相关代码如下,调用流程一般为:resumeHomeStackTask( )  --> moveHomeStackTaskToTop( )

    void moveHomeStackTaskToTop(int homeStackTaskType) {
        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
            mWindowManager.showRecentApps();
            return;
        }
        moveHomeStack(true);
        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
    }


    boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) {
        if (!mService.mBooting && !mService.mBooted) {
            // Not ready yet!
            return false;
        }

        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
            mWindowManager.showRecentApps();
            return false;
        }
        moveHomeStackTaskToTop(homeStackTaskType);
        if (prev != null) {
            prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
        }

        ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
        // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
        if (r != null && r.isHomeActivity()) {
            mService.setFocusedActivityLocked(r);
            return resumeTopActivitiesLocked(mHomeStack, prev, null);
        }
        return mService.startHomeActivityLocked(mCurrentUser);
    }
在mHomeStack中,除了会存放Launcher应用所在的TaskRecord,还会存放一个特别的Activity,它用于显示最近调用过的一些应用(RecentApps)。方便用户快捷地调用。


(3) 什么是mLastFocusedStack?

FrontStack可以简单地理解为当前最顶层的一个ActivityStack。那么mLastFocusedStack又是什么呢? 先看下他的定义。

    /** 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;
原生代码所带的注释其实已经讲得很清楚,他是用于保存上一个mFocusedStack,以顺利完成不同ActivityStack层次间切换的工作。

ActivityStackSupervisor可以通过以下方法获取mLastFocusedStack。

    ActivityStack getLastStack() {
        return mLastFocusedStack;
    }

二、ActivityStack分析

        管理ActivitiyRecord的一个栈。拥有管理TaskRecord的mTaskHistory、管理ActivityRecord的mLRUActivities、mNoAnimActivities。当前正在pause的Activity将其在AMS的ActivityRecord存在mPausingActivity中、上次被Pause的Activity对映的ActivityRecord存储在mLastPausedActivity里、当前显示的Activity的ActivityRecord存放在mResumedActivity里。ActivityStack的Handler中会对Activity生命周期回调操作进行超时处理。在android4.4后,ActivityStack中会有多个TaskRecord,每个TaskRecord中会存放该任务所拥有的ActivityRecord,这样管理起来就方便许多了。ActivityStack中对ActivityRecord的操作一般都是先从TaskRecord中查询到ActivityRecord,然后对其进行Activity生命周期的控制。

ActivityStack.java文件所在目录为:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

final class ActivityStack {
    ......//相关的参数
     
    //这个枚举变量列举了Activity在其生命周期中可能出现的状态。
    enum ActivityState {
        INITIALIZING,
        RESUMED,
        PAUSING,
        PAUSED,
        STOPPING,
        STOPPED,
        FINISHING,
        DESTROYING,
        DESTROYED
    }

    //AMS,WMS成员变量将在ActivityStack的构造函数里面实例化
    final ActivityManagerService mService;
    final WindowManagerService mWindowManager;

    /**
     * The back history of all previous (and possibly still
     * running) activities.  It contains #TaskRecord objects.
     */
    //管理所有TaskRecord的ArrayList,用于遍历,查找TaskRecord
    private ArrayList<TaskRecord> mTaskHistory = new ArrayList<TaskRecord>();
    ......//

    //------------------接下来将收录一些重要的方法,并以注释的方式对其进行解读。----------
    

    //类似于下面的topActivity()方法,返回一个最顶层的Activity,
    //不同的是:这里会跳过传入的参数ActivityRecord,即,除notTop之外的最顶层的Activity
    final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked(notTop);
            if (r != null) {
                return r;
            }
        }
        return null;
    }

    //topRunningActivityLocked()方法的重载,多加一个taskId参数。
    //从注释和代码逻辑都很容易理解:跳过符合taskId的TaskRecord及符合token的ActivityRecord
    /**
     * This is a simplified version of topRunningActivityLocked that provides a number of
     * optional skip-over modes.  It is intended for use with the ActivityController hook only.
     *
     * @param token If non-null, any history records matching this token will be skipped.
     * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
     *
     * @return Returns the HistoryRecord of the next activity on the stack.
     */
    final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            TaskRecord task = mTaskHistory.get(taskNdx);
            if (task.taskId == taskId) {
                continue;
            }
            ArrayList<ActivityRecord> activities = task.mActivities;
            for (int i = activities.size() - 1; i >= 0; --i) {
                final ActivityRecord r = activities.get(i);
                // Note: the taskId check depends on real taskId fields being non-zero
                // 跳过appToken与传入参数token相同的ActivityRecord
                if (!r.finishing && (token != r.appToken) && okToShowLocked(r)) {
                    return r;
                }
            }
        }
        return null;
    }

    //查找并返回最顶层的Activity,返回类型为ActivityRecord,这也验证了一个Activity对应一个ActivityRecord的说法
    //代码逻辑比较清晰,从栈顶的TaskRecord的最顶层Activity开始逐层往下遍历,找到的第一个正在运行的Activity便是topActivity
    //!r.finishing
    final ActivityRecord topActivity() {
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                final ActivityRecord r = activities.get(activityNdx);
                if (!r.finishing) {
                    return r;
                }
            }
        }
        return null;
    }

    //返回顶层的Task
    final TaskRecord topTask() {
        final int size = mTaskHistory.size();
        if (size > 0) {
            return mTaskHistory.get(size - 1);
        }
        return null;
    }

    //判断当前的ActivityStack是不是HomeStack
    final boolean isHomeStack() {
        return mStackId == HOME_STACK_ID;
    }

    final boolean isOnHomeDisplay() {
        return isAttached() &&
                mActivityContainer.mActivityDisplay.mDisplayId == Display.DEFAULT_DISPLAY;
    }

    final void moveToFront() {
        if (isAttached()) {
            if (isOnHomeDisplay()) {
                mStackSupervisor.moveHomeStack(isHomeStack());
            }
            mStacks.remove(this);
            mStacks.add(this);
        }
    }

    final boolean isAttached() {
        return mStacks != null;
    }

    ......//

    /**
     * Make sure that all activities that need to be visible (that is, they
     * currently can be seen by the user) actually are.
     */
    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
        ActivityRecord top = topRunningActivityLocked(null);
        if (top == null) {
            return;
        }
        if (DEBUG_VISBILITY) Slog.v(
                TAG, "ensureActivitiesVisible behind " + top
                + " configChanges=0x" + Integer.toHexString(configChanges));

        if (mTranslucentActivityWaiting != top) {
            mUndrawnActivitiesBelowTopTranslucent.clear();
            if (mTranslucentActivityWaiting != null) {
                // Call the callback with a timeout indication.
                notifyActivityDrawnLocked(null);
                mTranslucentActivityWaiting = null;
            }
            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
        }

        // If the top activity is not fullscreen, then we need to
        // make sure any activities under it are now visible.
        boolean aboveTop = true;
        //如果当前ActivityStack之上的任一Stack中,有一个FullScreen的Activity,isStackVisible()这个函数返回true
        //否则,当前Stack就是hidden状态的,即isStackVisble == false.
        //因此behindFullScreen这个变量也很好理解,可理解为“当前ActivityStack是否在FullScreen的Activity的下面”
        boolean behindFullscreen = !isStackVisible();

        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            final TaskRecord task = mTaskHistory.get(taskNdx);
            final ArrayList<ActivityRecord> activities = task.mActivities;
            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                final ActivityRecord r = activities.get(activityNdx);
                if (r.finishing) {
                    continue;
                }
                //加入这个逻辑是skip掉top之上的那些Activity,为什么除去呢,
                //因为top是计算出来的top running Activity,top之上的Activity必然不是running,要么是finishing等。
                if (aboveTop && r != top) { 
                    continue;
                }
                aboveTop = false;
                // mLaunchingBehind: Activities launching behind are at the back of the task stack
                // but must be drawn initially for the animation as though they were visible. 
                // |as thougn: 好像,仿佛|
                if (!behindFullscreen || r.mLaunchTaskBehind) {
                    if (DEBUG_VISBILITY) Slog.v(
                            TAG, "Make visible? " + r + " finishing=" + r.finishing
                            + " state=" + r.state);

                    // First: if this is not the current activity being started, make
                    // sure it matches the current configuration.
                    if (r != starting) {
                        ensureActivityConfigurationLocked(r, 0);
                    }

                    if (r.app == null || r.app.thread == null) {
                        // This activity needs to be visible, but isn't even
                        // running...  get it started, but don't resume it
                        // at this point.
                        if (DEBUG_VISBILITY) Slog.v(TAG, "Start and freeze screen for " + r);
                        if (r != starting) {
                            //这个逻辑如何理解呢?就是 如果starting不是Fullscreen,那么starting之下的还未启动的activity应该要可见,但现在又不能resume,此时先 startFreezingScreenLocked()冻结; 
                            r.startFreezingScreenLocked(r.app, configChanges);
                        }
                        if (!r.visible || r.mLaunchTaskBehind) {
                            if (DEBUG_VISBILITY) Slog.v(
                                    TAG, "Starting and making visible: " + r);
                            setVisibile(r, true);
                        }
                        if (r != starting) {
                            mStackSupervisor.startSpecificActivityLocked(r, false, false);
                        }

                    } else if (r.visible) {
                        // If this activity is already visible, then there is nothing
                        // else to do here.
                        if (DEBUG_VISBILITY) Slog.v(TAG, "Skipping: already visible at " + r);
                        r.stopFreezingScreenLocked(false);
                        try {
                            if (r.returningOptions != null) {
                                r.app.thread.scheduleOnNewActivityOptions(r.appToken,
                                        r.returningOptions);
                            }
                        } catch(RemoteException e) {
                        }
                    } else {
                        // This activity is not currently visible, but is running.
                        // Tell it to become visible.
                        r.visible = true;
                        if (r.state != ActivityState.RESUMED && r != starting) {
                            // If this activity is paused, tell it
                            // to now show its window.
                            if (DEBUG_VISBILITY) Slog.v(
                                    TAG, "Making visible and scheduling visibility: " + r);
                            try {
                                if (mTranslucentActivityWaiting != null) {
                                    r.updateOptionsLocked(r.returningOptions);
                                    mUndrawnActivitiesBelowTopTranslucent.add(r);
                                }
                                setVisibile(r, true);
                                r.sleeping = false;
                                r.app.pendingUiClean = true;
                                r.app.thread.scheduleWindowVisibility(r.appToken, true);
                                r.stopFreezingScreenLocked(false);
                            } catch (Exception e) {
                                // Just skip on any failure; we'll make it
                                // visible when it next restarts.
                                Slog.w(TAG, "Exception thrown making visibile: "
                                        + r.intent.getComponent(), e);
                            }
                        }
                    }

                    // Aggregate current change flags.
                    configChanges |= r.configChangeFlags;
                    //这个逻辑的的意思是,如果将当期的一个FullScreen属性的Activity设置为了可见,那么它就将遮挡下面的其余Activity
                    //将behindFullScreen设置为true后,只要不是mLaunchTaskBehind的Activity,都不会进这个流程
                    if (r.fullscreen) {
                        // At this point, nothing else needs to be shown
                        if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r);
                        behindFullscreen = true;
                    } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
                        if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
                        behindFullscreen = true;
                    }
                } else {
                    //前面已经找到一个Fullscreen Activity,所以这些位于Fullscreen Activity之下的Activity是不可见的,因此如果这个activity是可见的,那么就把它设为不可见状态;比如从一个activity拉起另一个Fullscreen Activity,那么前一个activity就会位于后一个activity之下,这时此处便把前一个activity设为不可见;
                    //如果是从一个ActivityStack跳到另一个ActivityStack,比如从launcher启动一个应用,那么launcher便在此设为不可见;或者从其他应用回到launcher,那么其他应用的activity便在此设为不可见(跟behindFullscreen的初始值相关)。  
                    if (DEBUG_VISBILITY) Slog.v(
                        TAG, "Make invisible? " + r + " finishing=" + r.finishing
                        + " state=" + r.state
                        + " behindFullscreen=" + behindFullscreen);
                    // Now for any activities that aren't visible to the user, make
                    // sure they no longer are keeping the screen frozen.
                    if (r.visible) {
                        if (DEBUG_VISBILITY) Slog.v(TAG, "Making invisible: " + r);
                        try {
                            setVisibile(r, false);
                            switch (r.state) {                                                          
                                //stop状态的Activity,直接将调用 scheduleWindowVisibility()来更改window的可见性。
                                case STOPPING:  
                                case STOPPED:
                                    if (r.app != null && r.app.thread != null) {
                                        if (DEBUG_VISBILITY) Slog.v(
                                                TAG, "Scheduling invisibility: " + r);
                                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
                                    }
                                    break;

                                case INITIALIZING:
                                case RESUMED:
                                case PAUSING:
                                case PAUSED:
                                    // This case created for transitioning activities from
                                    // translucent to opaque {@link Activity#convertToOpaque}.
                                    if (getVisibleBehindActivity() == r) {
                                        releaseBackgroundResources();
                                    } else {
                                        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
                                            //既然activity不可见了,那么就把这个activity加入 mStoppingActivities中;
                                            mStackSupervisor.mStoppingActivities.add(r);  
                                        }
                                        mStackSupervisor.scheduleIdleLocked(); //触发内存回收机制
                                    }
                                    break;

                                default:
                                    break;
                            }
                        } catch (Exception e) {
                            // Just skip on any failure; we'll make it
                            // visible when it next restarts.
                            Slog.w(TAG, "Exception thrown making hidden: "
                                    + r.intent.getComponent(), e);
                        }
                    } else {
                        if (DEBUG_VISBILITY) Slog.v(TAG, "Already invisible: " + r);
                    }
                }
            }
        }

        if (mTranslucentActivityWaiting != null &&
                mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
            // Nothing is getting drawn or everything was already visible, don't wait for timeout.
            notifyActivityDrawnLocked(null);
        }
    }

    //移除指定的TaskRecord
    void removeTask(TaskRecord task) {
        mStackSupervisor.endLockTaskModeIfTaskEnding(task);
        mWindowManager.removeTask(task.taskId);
        final ActivityRecord r = mResumedActivity;
        if (r != null && r.task == task) {
            mResumedActivity = null;
        }

        final int taskNdx = mTaskHistory.indexOf(task);
        final int topTaskNdx = mTaskHistory.size() - 1;
        if (task.isOverHomeStack() && taskNdx < topTaskNdx) {
            final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1);
            if (!nextTask.isOverHomeStack()) {
                nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
            }
        }
        mTaskHistory.remove(task);
        updateTaskMovement(task, true);

        if (task.mActivities.isEmpty()) {
            final boolean isVoiceSession = task.voiceSession != null;
            if (isVoiceSession) {
                try {
                    task.voiceSession.taskFinished(task.intent, task.taskId);
                } catch (RemoteException e) {
                }
            }
            if (task.autoRemoveFromRecents() || isVoiceSession) {
                // Task creator asked to remove this when done, or this task was a voice
                // interaction, so it should not remain on the recent tasks list.
                mService.mRecentTasks.remove(task);
                task.removedFromRecents(mService.mTaskPersister);
            }
        }

        if (mTaskHistory.isEmpty()) {
            if (DEBUG_STACK) Slog.i(TAG, "removeTask: moving to back stack=" + this);
            if (isOnHomeDisplay()) {
                mStackSupervisor.moveHomeStack(!isHomeStack());
            }
            if (mStacks != null) {
                mStacks.remove(this);
                mStacks.add(0, this);
            }
            mActivityContainer.onTaskListEmptyLocked();
        }
    }

    //新建一个新的TaskRecord,并把它加入到ActivtyStack栈中,toTop参数表明是否加到栈顶
    TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            boolean toTop) {
        //调用TaskRecord的构造函数
        TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
                voiceInteractor);
        //this(ActivityStack).addTask
        addTask(task, toTop, false);
        return task;
    }

    //返回一个保存了所有TaskRecord的ArrayList副本
    ArrayList<TaskRecord> getAllTasks() {
        return new ArrayList<TaskRecord>(mTaskHistory);
    }

    
    void addTask(final TaskRecord task, final boolean toTop, boolean moving) {
        task.stack = this;
        if (toTop) {
            insertTaskAtTop(task);
        } else {
            mTaskHistory.add(0, task);
            updateTaskMovement(task, false);
        }
        if (!moving && task.voiceSession != null) {
            try {
                task.voiceSession.taskStarted(task.intent, task.taskId);
            } catch (RemoteException e) {
            }
        }
    }
    
    public int getStackId() {
        return mStackId;
    }

}


三、TaskRecord、ActivityRecord分析

(待续)

四、Activity的生命周期





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:12332次
    • 积分:298
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:11篇
    • 译文:0篇
    • 评论:3条
    最新评论