Activity管理笔记

文章仅记录自己学习该模块时的一点理解,看到哪写到哪,所以特别散。


AMS管理四大组件外加进程管理,其中最庞大的算是Activity了吧。

1、AMS中对ActivityStack划分为两类,其中一类是FrontStack,另一类刚好相反。

  boolean isFrontStack(ActivityStack stack) {
        return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
    }


   ActivityStack getFocusedStack() {
        if (mFocusedStack == null) {
            return mHomeStack;
        }
        switch (mStackState) {
            case STACK_STATE_HOME_IN_FRONT:
            case STACK_STATE_HOME_TO_FRONT:
                return mHomeStack;
            case STACK_STATE_HOME_IN_BACK:
            case STACK_STATE_HOME_TO_BACK:
            default:
                return mFocusedStack;
        }
    }

从上面的代码可以得出以下结论:

A )、对于4.4目前只有两个ActivityStack的逻辑很清晰:HomeStack、AStack

a、如果getFocusedStack()==HomeStack,那么HomeStack就是FrontStack,另一个就是非FrontStack。

b、如果getFocusedStack()==    AStack,那么HomeStack就是非FrontStack,另一个就是FrontStack。 

B )、如果做成**至少有三个ActivityStack:HomeStack、AStack、BStack

a、如果getFocusedStack()==HomeStack,那么HomeStack就是FrontStack,AStack、BStack就是非FrontStack。

b、如果getFocusedStack()==       AStack,那么HomeStack就是非FrontStack,AStack、BStack就是FrontStack。

c、如果getFocusedStack()==       BStack,那么HomeStack就是非FrontStack,AStack、BStack就是FrontStack。

按照现有的逻辑来说,HomeStack跟其他所有ActivityStack是完全相反的,其他所有ActivityStack要么都是FrontStack,要么都是非FrontStack。那它这个isFrontStack分类有啥用?出于什么目的而设计的?

2、AMS中对Activity的管理是通过任务栈的形式来管理的,也就是利用TaskRecord代表Task,系统中有很多Task,所以就出现了Task栈——ActivityStack,按理说只要一个ActivityStack就OK了,但是Android4.4有两个ActivityStack,并且还可以有多个,这个确实是为**设计的。

问题一:ActivityStackSupervisor是如何管理ActivityStack的呢?

问题二:ActivityStack是如何管理TaskRecord的呢?

问题三:TaskRecord如何管理ActivityRecord的呢?

这三个问题下面一一来研究。

问题一:ActivityStackSupervisor是如何管理ActivityStack的呢?

ActivityStackSupervisor是一个管理ActivityStack类,里面的函数应该可以给出上面的答案。相关函数主要有adjustStackFocus()、getFocusedStack()、setFocusedStack()等,这几个函数比较有意思,下面来研究下。但是首先必须要搞清楚mFocusedStack是个什么东西,不然代码没法看。google源码是这样解释的这个变量的:

  /** The non-home stack currently receiving input or launching the next activity. If home is
     * in front then mHomeStack overrides mFocusedStack.
     * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
上面的解释说了跟没说一样。其实这个变量应该这么理解:google把ActivityStack分为两类,一类是包含Launcher和后台界面ActivityRecord的mHomeStack,另一类是包含普通应用ActivityRecord的“普通ActivityStack”,mFocusedStack就是所有“普通ActivityStack”中的“焦点ActivityStack”,所谓“焦点ActivityStack”就是接受输入事件和启动下一个Activity,只要存在“普通ActivityStack”,那么mFocusedStack就不为null。但是“终极焦点ActivityStack”是在mHomeStack和所有“普通ActivityStack”中的“焦点ActivityStack”——mFocusedStack”中进行对决产生的,对决函数就是getFocusedStack(),对决策略就是判断mStackState状态值来选择mHomeStack或是mFocusedStack。注意,如果系统中没有启动过普通应用Activity,或是普通应用Activity都被移除了(“普通ActivityStack”中的Task被全部移除掉时会自动销毁掉这个“普通ActivityStack”,所以就会出现不存在“普通ActivityStack”),那么就不存在“普通ActivityStack”,也就是mFocusedStack为null,此时etFocusedStack()自然直接返回mHomeStack。可能是Launcher是个比较特殊的Activity,mHomeStack跟跟“普通ActivityStack”区别很大,如果不加区分地进行统一设计,那么可能代码更加复杂。理解了mFocusedStack,再来研究上面几个函数,so easy!!!

Ⅰ、先看adjustStackFocus()

   ActivityStack adjustStackFocus(ActivityRecord r)  {
        final TaskRecord task = r.task;
        if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
            if (task != null) {
                final ActivityStack taskStack = task.stack;
                if (mFocusedStack != taskStack) {
                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
                            "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
                    mFocusedStack = taskStack.isHomeStack() ? null : taskStack;
                } else {
                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
                        "adjustStackFocus: Focused stack already=" + mFocusedStack);
                }
                return taskStack;
            }

            if (mFocusedStack != null) {
                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
                        "adjustStackFocus: Have a focused stack=" + mFocusedStack);
                return mFocusedStack;
            }

            for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
                ActivityStack stack = mStacks.get(stackNdx);
                if (!stack.isHomeStack()) {
                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
                            "adjustStackFocus: Setting focused stack=" + stack);
                    mFocusedStack = stack;
                    return mFocusedStack;
                }
            }

            // Time to create the first app stack for this user.
            int stackId =
                    mService.createStack(-1, HOME_STACK_ID, StackBox.TASK_STACK_GOES_OVER, 1.0f);
            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
                    " stackId=" + stackId);
            mFocusedStack = getStack(stackId);
            return mFocusedStack;
        }
        return mHomeStack;
    }

adjustStackFocus()函数在startActivityUncheckedLocked()中调用,也就是说当起来一个Activity时,adjustStackFocus()函数修正Activity导致对mFocusedStack的影响。adjustStackFocus(r)函数的功能是根据参数r来调整mFocusedStack值,调整完mFocusedStack值,然后紧接着调用moveHomeStack()来修正mHomeStack的状态。具体调整规则是:

①如果启动的Activity是HOME_ACTIVITY_TYPE和RECENTS_ACTIVITY_TYPE类型,那么直接返回mHomeStack,然后利用moveHomeStack()将mHomeStack设为前台Stack。

②如果启动的Activity是APPLICATION_ACTIVITY_TYPE类型,那么又细分三种情况:A、如果不存在“普通ActivityStack”,那么直接调用AMS.createStack()创建一个“普通ActivityStack”;B、如果存在“普通ActivityStack”,那么直接返回mFocusedStack;C、如果r指定了某个“普通ActivityStack”,那么返回指定的ActivityStack,并把mFocusedStack设为指定的ActivityStack;

Ⅱ、setFocusedStack()

    void setFocusedStack(ActivityRecord r)  {
        if (r == null) {
            return;
        }
        if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {  //①这个条件是针对Launcher和后台Activity的,所以只要把mStackState设为STACK_STATE_HOME_TO_FRONT,对决函数getFocusedStack()返回的便是mHomeStack。

            if (mStackState != STACK_STATE_HOME_IN_FRONT) {
                if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
                        stackStateToString(mStackState) + " new=" +
                        stackStateToString(STACK_STATE_HOME_TO_FRONT) +
                        " Callers=" + Debug.getCallers(3));
                mStackState = STACK_STATE_HOME_TO_FRONT;
            }
        } else {                                                                     //②非Launcher和非后台Activity,走的便是这个逻辑。

            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
                    "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
                    " Callers=" + Debug.getCallers(3));
            final ActivityStack taskStack = r.task.stack;
            mFocusedStack = taskStack.isHomeStack() ? null : taskStack;    //③这行代码其实只要写成mFocusedStack =taskStack便可,因为taskStack不可能为mHomeStack的,这个是在②中限制住的。将mStackState = STACK_STATE_HOME_TO_BACK,那么对决函数getFocusedStack()返回的便是mFocusedStack 。
            if (mStackState != STACK_STATE_HOME_IN_BACK) {
                if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
                        stackStateToString(mStackState) + " new=" +
                        stackStateToString(STACK_STATE_HOME_TO_BACK) +
                        " Callers=" + Debug.getCallers(3));
                mStackState = STACK_STATE_HOME_TO_BACK;
            }
        }
    }
setFocusedStack()函数就是设置mStackState 的状态值来间接影响getFocusedStack()的返回值。

总结:研究这两个函数,可以看出AMS对ActivityTask的管理是分为两种类型来管理的。

问题二:ActivityStack是如何管理TaskRecord的呢?

TaskRecord代表一个Task。如果新启动的Activity运行在新的Task中,那么就需要创建一个TaskRecord,在哪些情况下Activity需要运行在新的Task中呢?回答这个问题需要仔细研究startActivity()流程。下面来仔细研究下Activity启动流程。

startActivity()

任何Activity的启动都会调用startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options)。解释下几个重要的参数,caller就是start该Activity的进程,resultTo是要将startActivity的结果返回给哪个Activity,比如startActivityForResult()。至于resultTo究竟是个什么类型的Binder对象呢?这个跟踪下源码就知道了,给出具体调用流程:startActivity()-->startActivityAsUser()-->startActivityMayWait()-->startActivityLocked()-->new ActivityRecord();new Token();-->startActivityUncheckedLocked()-->ActivityStack.startActivityLocked()-->ActivityStackSupervisor.resumeTopActivitiesLocked()-->ActivityStack.resumeTopActivityLocked()-->ActivityStackSupervisor.startSpecificActivityLocked()-->realStartActivityLocked()-->ActivityThread.scheduleLaunchActivity()-->r.token = token;从这个流程中可以知道Activity.mToken保存的是AMS侧对应的ActivityRecord.appToken的Binder代理对象。

随便看:

Ⅰ、ActivityRecord.startLaunchTickingLocked(),记录Activity的启动时间点,同时会调用continueLaunchTickingLocked()来post一个延迟ActivityStack.LAUNCH_TICK毫秒的LAUNCH_TICK_MSG消息。Activity在LAUNCH_TICK时间内起来了必然调用会调用finishLaunchTickingLocked()来清除launchTickTime变量值,并打印一条日志;如果Activity起来的慢,那么post的延迟消息必然先执行,这个消息又执行continueLaunchTickingLocked()函数,如此循环直到Activity起来为止。这个机制就是定时打日志记录Activity的启动快慢用的。

Ⅱ、Activity.mPausingActivity,在startPausingLocked()时会将要paused的ActivityRecord保存在mPausingActivity中,当pause成功后会调用activityPausedLocked()函数做后续处理,在这个函数中会将mPausingActivity重置为null。这个过程与Google对这个变量的描述一致:“ When we are in the process of pausing an activity, before starting the next one, this variable holds the activity that is currently being paused.”。

Ⅲ、startPausingLocked()这个函数有很多很重要的学习点,重点研究下。

 final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
        if (mPausingActivity != null) {              //①如果要pause一个Activity时,已经有一个Activity在pause还未完成(pause完成的话mPausingActivity 为null),那么抛出一个异常。
            Slog.e(TAG, "Trying to pause when pause is already pending for "
                  + mPausingActivity, new RuntimeException("here").fillInStackTrace());
        }
        ActivityRecord prev = mResumedActivity;        //②mResumedActivity中保存的是当前resume的Activity,pause的对象肯定是当前的resume的Activity,如果当前没有resume对象,这种情况也就是系统启动第一个Activity才有的情况,此时就直接resume Activity栈中的顶层Activity。

        if (prev == null) {
            Slog.e(TAG, "Trying to pause when nothing is resumed",
                    new RuntimeException("here").fillInStackTrace());
            mStackSupervisor.resumeTopActivitiesLocked();
            return;
        }
        if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
        else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
        mResumedActivity = null;   //③当前resume的Activity要被pause掉了,那么mResumedActivity必然要重置为null了,同时mPausingActivity指向当前resumed的Activity。
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
        prev.state = ActivityState.PAUSING;      //④要pause的ActivityRecord.state状态设置为PAUSING
        prev.task.touchActiveTime();
        clearLaunchTime(prev);
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();  //⑤取出要Start的ActivityRecord。

        stopFullyDrawnTraceIfNeeded();

        mService.updateCpuStats();

        if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        prev.userId, System.identityHashCode(prev),
                        prev.shortComponentName);
                mService.updateUsageStats(prev, false);
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags);              //⑥回调上层应用ActivityThread的schedulePauseActivity()函数,做一些应用层的处理工作。

            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }

        // If we are not going to sleep, we want to ensure the device is
        // awake until the next activity is started.
        if (!mService.isSleepingOrShuttingDown()) {
            mStackSupervisor.acquireLaunchWakelock();     //⑦获取一个唤醒锁,防止系统睡眠,获取唤醒锁时要注意释放,看解释知道在Activity完全起来后必然会释放这个锁,但是如果出现异常呢?Google代码写的很健壮,在获取一个唤醒锁时,同时也会post一个超时消息,如果超时了还没释放这个锁,那么就在这个超时消息处理中释放唤醒锁。
        }

        if (mPausingActivity != null) {
            // Have the window manager pause its key dispatching until the new
            // activity has started.  If we're pausing the activity just because
            // the screen is being turned off and the UI is sleeping, don't interrupt
            // key dispatch; the same activity will pick it up again on wakeup.
            if (!uiSleeping) {
                prev.pauseKeyDispatchingLocked();   //⑧pause一个Activity时,需要关闭这个Activity的输入事件通道,关闭一个输入通道只需将与该Activity对应的WindowToken.paused设为true,然后调用updateInputWindowsLw(true)将窗口状态更新到InputDispatcher中,InputDispatcher分发消息时是不会分发给paused状态窗口的,以此达到关闭输入通道效果。
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
            }

            // Schedule a pause timeout in case the app doesn't respond.
            // We don't give it much time because this directly impacts the
            // responsiveness seen by the user.
            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);   //⑨post一个PAUSE_TIMEOUT_MSG消息,为什么要post这么个消息,是因为如果无法完成paused前一个Activity,那么就无法start下一个Activity,这个超时消息是防止异常导致无法及时start下一个Activity,在超时消息处理函数中肯定有start next Activity的逻辑。
            msg.obj = prev;
            prev.pauseTime = SystemClock.uptimeMillis();
            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
            if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");
        } else {
            // This activity failed to schedule the
            // pause, so just treat it as being paused now.
            if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
            mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
        }
    }

从上面这个函数中可以看到要写一个健壮的代码需要考虑异常导致无法完成下一步工作,此时可以利用超时机制来启动下一步工作。

Ⅳ、stopActivityLocked()函数。

    final void stopActivityLocked(ActivityRecord r) {
        if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);
        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {  //①只要设置了FLAG_ACTIVITY_NO_HISTORY和FLAG_NO_HISTORY属性,当stop一个Activity时,直接finish掉该Activity。
            if (!r.finishing) {           //②Activity.finishing表示这个Activity正在finish
                if (!mService.mSleeping) {
                    if (DEBUG_STATES) {
                        Slog.d(TAG, "no-history finish of " + r);
                    }
                    requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "no-history", false);
                } else {
                    if (DEBUG_STATES) Slog.d(TAG, "Not finishing noHistory " + r
                            + " on stop because we're just sleeping");
                }
            }
        }

        if (r.app != null && r.app.thread != null) {
            adjustFocusedActivityLocked(r);    //③调整AMS.mFocusedActivity值,看源码在启动一个Activity调用startActivityUncheckedLocked()时便调用 mService.setFocusedActivityLocked(r)重置了mFocusedActivity值。
            r.resumeKeyDispatchingLocked();    //④要stop一个Activity了为什么要打开这个Activity的输入通道??打开输入通道只有在完成pause Activity(completePauseLocked())和完成 resume Activity(completeResumeLocked())时才调用嘛,为啥要准备stop一个Activity时也要打开输入通道??
            try {
                r.stopped = false;      //⑤设置ActivityRecord.stoped为FALSE,因为这个Activity确实还没完全stop下来。
                if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPING: " + r
                        + " (stop requested)");
                r.state = ActivityState.STOPPING;   //⑥设置ActivityRecord.state为STOPPING状态
                if (DEBUG_VISBILITY) Slog.v(
                        TAG, "Stopping visible=" + r.visible + " for " + r);
                if (!r.visible) {
                    mWindowManager.setAppVisibility(r.appToken, false);    //⑤stop一个Activity时设置该Activity的窗口不可见。
                }
                r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);   //回调应用层的stop处理函数。
                if (mService.isSleepingOrShuttingDown()) {        //⑥当系统正准备要sleeping或shutdown时,将这个Activity进行sleep处理。在什么情况下需要sleep一个Activity呢?当系统要sleep,并且这个Activity的状态为stopping或stoped时便把这个Activity进行sleep处理。
                    r.setSleeping(true);
                }
                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
                mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
            } catch (Exception e) {
                // Maybe just ignore exceptions here...  if the process
                // has crashed, our death notification will clean things
                // up.
                Slog.w(TAG, "Exception thrown during pause", e);
                // Just in case, assume it to be stopped.
                r.stopped = true;
                if (DEBUG_STATES) Slog.v(TAG, "Stop failed; moving to STOPPED: " + r);
                r.state = ActivityState.STOPPED;
                if (r.configDestroy) {
                    destroyActivityLocked(r, true, false, "stop-except");
                }
            }
        }
    }


3、activityIdleInternalLocked()

    // Checked.
    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            Configuration config) {
        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);

        ArrayList<ActivityRecord> stops = null;
        ArrayList<ActivityRecord> finishes = null;
        ArrayList<UserStartedState> startingUsers = null;
        int NS = 0;
        int NF = 0;
        IApplicationThread sendThumbnail = null;
        boolean booting = false;
        boolean enableScreen = false;
        boolean activityRemoved = false;

        ActivityRecord r = ActivityRecord.forToken(token);    //①如果传进来的参数token不为null,将代表参数token的ActivityRecord.idle 设为true。
        if (r != null) {
            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
                    Debug.getCallers(4));
            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
            r.finishLaunchTickingLocked();
            if (fromTimeout) {
                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
            }

            // This is a hack to semi-deal with a race condition
            // in the client where it can be constructed with a
            // newer configuration from when we asked it to launch.
            // We'll update with whatever configuration it now says
            // it used to launch.
            if (config != null) {
                r.configuration = config;
            }

            // We are now idle.  If someone is waiting for a thumbnail from
            // us, we can now deliver.
            r.idle = true;

            if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
                sendThumbnail = r.app.thread;
                r.thumbnailNeeded = false;
            }

            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
            if (!mService.mBooted && isFrontStack(r.task.stack)) {
                mService.mBooted = true;
                enableScreen = true;
            }
        }

        if (allResumedActivitiesIdle()) {            //②如果所有ActivityStack.mResumedActivity.idle为true,。。。。
            if (r != null) {
                mService.scheduleAppGcsLocked();
            }

            if (mLaunchingActivity.isHeld()) {
                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
                if (VALIDATE_WAKE_LOCK_CALLER &&
                        Binder.getCallingUid() != Process.myUid()) {
                    throw new IllegalStateException("Calling must be system uid");
                }
                mLaunchingActivity.release();
            }
            ensureActivitiesVisibleLocked(null, 0);
        }

        // Atomically retrieve all of the other things to do.
        stops = processStoppingActivitiesLocked(true);   //③将mStoppingActivities中不可见的Activity进行返回,在第⑦中进行进一步处理
        NS = stops != null ? stops.size() : 0;
        if ((NF=mFinishingActivities.size()) > 0) {        //④清除mFinishingActivities,并在第⑧中进一步进行处理
            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
            mFinishingActivities.clear();
        }

        final ArrayList<ActivityRecord> thumbnails;
        final int NT = mCancelledThumbnails.size();
        if (NT > 0) {                         //⑤清除mCancelledThumbnails,并在第⑥中进一步处理
            thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails); 
            mCancelledThumbnails.clear();
        } else {
            thumbnails = null;
        }

        if (isFrontStack(mHomeStack)) {
            booting = mService.mBooting;
            mService.mBooting = false;
        }

        if (mStartingUsers.size() > 0) {          
            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
            mStartingUsers.clear();
        }

        // Perform the following actions from unsynchronized state.
        final IApplicationThread thumbnailThread = sendThumbnail;
        mHandler.post(new Runnable() {       //⑥处理thumbnails,干嘛的?
            @Override
            public void run() {
                if (thumbnailThread != null) {
                    try {
                        thumbnailThread.requestThumbnail(token);
                    } catch (Exception e) {
                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
                        mService.sendPendingThumbnail(null, token, null, null, true);
                    }
                }

                // Report back to any thumbnail receivers.
                for (int i = 0; i < NT; i++) {
                    ActivityRecord r = thumbnails.get(i);
                    mService.sendPendingThumbnail(r, null, null, null, true);
                }
            }
        });

        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NS; i++) {                 //⑦处理processStoppingActivitiesLocked()返回的Activity,如果这个Activity正在finish,那么直接调用finishCurrentActivityLocked()立即finish掉,否则调用stopActivityLocked()来stop这些Activity。
            r = stops.get(i);
            final ActivityStack stack = r.task.stack;
            if (r.finishing) {
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
            } else {
                stack.stopActivityLocked(r);
            }
        }

        // Finish any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NF; i++) {       //⑧destroy掉mFinishingActivities中的Activity。
            r = finishes.get(i);
            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
        }

        if (booting) {
            mService.finishBooting();
        } else if (startingUsers != null) {
            for (int i = 0; i < startingUsers.size(); i++) {
                mService.finishUserSwitch(startingUsers.get(i));
            }
        }

        mService.trimApplications();           //⑨精简进程,回收内存。
        //dump();
        //mWindowManager.dump();

        if (enableScreen) {
            mService.enableScreenAfterBoot();
        }

        if (activityRemoved) {
            resumeTopActivitiesLocked();
        }

        return r;
    }

这个函数主要是将StoppingActivities进行finish或直接stop掉,FinishingActivities进行destroy掉,最后再调用trimApplications()精简进程,回收内存。

4. isActivityOverHome()函数分析

    boolean isActivityOverHome(ActivityRecord record) {
        // Start at record and go down, look for either home or a visible fullscreen activity.
        final TaskRecord recordTask = record.task;
        for (int taskNdx = mTaskHistory.indexOf(recordTask); taskNdx >= 0; --taskNdx) {
            TaskRecord task = mTaskHistory.get(taskNdx);
            final ArrayList<ActivityRecord> activities = task.mActivities;
            final int startNdx =
                    task == recordTask ? activities.indexOf(record) : activities.size() - 1;
            for (int activityNdx = startNdx; activityNdx >= 0; --activityNdx) {
                final ActivityRecord r = activities.get(activityNdx);
                if (r.isHomeActivity()) {
                    return true;
                }
                if (!r.finishing && r.fullscreen) {
                    // Passed activity is over a fullscreen activity.
                    return false;
                }
            }
            if (task.mOnTopOfHome) {
                // Got to the bottom of a task on top of home without finding a visible fullscreen
                // activity. Home is visible.
                return true;
            }
        }
        // Got to the bottom of this stack and still don't know. If this is over the home stack
        // then record is over home. May not work if we ever get more than two layers.
        return mStackSupervisor.isFrontStack(this);
    }
这个函数用来判断launcher是否显示在给出的activity之下,如果显示在给出的activity之下,那么返回true,否则返回false。

你可能感兴趣的:(Activity管理笔记)