分析Activity的生命周期管理,我觉得应该先看下面两篇关于Activity的官方文档:
了解 Activity 生命周期
处理 Activity 状态更改

里面有下面一段话,比较简洁的说出了Activity生命周期。

常见的触发Activity生命周期变更的方式有几种
1 上面的Activity finish露出下面的Activity。
2 一个Activity启动另外一个Activity,然后调用者finish。
3 一个Activity启动另外一个Activity,然后调用者不finish。
4 onNewIntent。
5 通过最近任务恢复Activity。

这里面最为复杂的就是2和3这两种情况,在我们实际使用Android手机过程中,大多数情况是先调用启动Activiy再调用finish,所以很多时候3流程是流程2的一部分,也就是图1 Activity协调这段话中描述的生命周期,假设ActivityA 启动ActivityB。 整个生命周期流程是这样的。
ActivityB.onPause() -> ActivityA.onCreate() -> ActivityA.onStart()-> ActivityA.onResume()->ActivityB.onStop()


文档中还说要把执行cpu相对密集的操作放在onStop()里面。为什么这么做呢,在ActivityA刚刚启动的过程中,应该是应用最繁忙的时候,将cpu密集的操作放在ActivityB的onStop操作中会不会影响ActivityA的启动速度(ActivityA和ActivityB通常在一个进程里面,共用一个主线程)?这里Android是有考量的,ActivityB的onStop操作并不会在ActivityA.onResume执行后马上执行,要等到ActivityA所在进程的主进程进入Idle状态才会触发ActivityB的stop函数。

为了实现上述生命周期管理,ActivityManagerService的实现大概如下图:

这个图看起来比较复杂,图中删除了一些中间函数,只保留了关键函数。这里我来说明下,首先在启动Activity时,在准备好stask和task后,调用ActivityStack.resumeTopActivityLocked() 函数来显示栈顶的Activity,ActivityStack.resumeTopActivityLocked() 函数可能是处理Activity的关闭,也可能处理新Activity的启动,从函数名字可以看出来,函数只是用户resume栈顶Activity。 在启动新Activity过程中,发现栈上存在resumed状态的Activity,就会先调用ActivityStack.startPausingLocked()函数来pause当前栈上resumed的Activity。 这个过程会通过ActivityThread的binder对象调用到App进程中ActivityThread.schedulePauseActivity()函数。ActivityThread.schedulePauseActivity()函数发送一个系统Message给app主线程,App主线程收到消息调用ActivityThread.handlePauseActivity()函数,ActivityStack.resumeTopActivityLocked() 返回。 App端ActivityThread.handlePauseActivity()函数会调用Activity.onPause()方法,执行完Activity.onPause() 函数后ActivityThread.handlePauseActivity()函数调用ActivityManagerService.activityPauseLock()函数通知AMS应用的Activity pause完成,这时候就可以去resume 栈上的activity了。对于ActivityStack.startPausingLocked()调用App进程来进行pause, 由于用户进程不一定可靠,有可能超时, ActivityStack.startPausingLocked()函数还留了一手,就是发送一个延时500ms的PAUSE_TIMEOUT_MSG消息出去,如果App端500ms内没有处理完Ams的pause请求,该消息就会被处理。对于PAUSE_TIME_MSG超时消息的处理(3.2),和App端调用ActivityManagerService.activityPauseLock()的情况(分支7),最终都会调用到ActivityStack.activityPauseLocked()函数。该函数调用ActivityStack.completePaused()函数来处理pause完成。 这个函数会调用ActivityStack.resumeTopActivityLocked() 函数(注意又调用了ActivityStack.resumeTopActivityLocked(),这时stack上的resume activity已经不存在了,所以不需要再pauseActivity, 直接进入启动新Activity流程, 启动新Activity是通过ActivityStackSupervisor.startSpecificActivityLocked()函数完成的,该函数调用了ActivityStackSupervisor.relStartActivityLocked()函数,最终调用到App端的ActivityThread.scheduleLaunchActivity(). 对于客户端的调用也是异步的, 客户端会依次调用Activity.onCreate(), Activity.onStart()以及Activity.onResume()。同时
ActivityStackSupervisor.relStartActivityLocked()函数会调用ActivityStackSupervisor.minimalResumeActivityLocked()函数,ActivityStackSupervisor.minimalResumeActivityLocked()函数调用ActivityStack.completeResumeLocked() 处理Activity启动完成消息(注意这里并没有等待客户端Activity.onResume()完成)。ActivityStack.completeResumeLocked() 函数会发送一个延迟10s的IDLE_TIMEOUT消息等待App端idle超时,如15.1。 同时客户端这边,当主线程MessageQueue中没有马上要处理的消息的时候会调用ActivityThread.Idler.queueIdle()函数,该函最终会调用到ActivityStack.activityIdleInternalLocked()函数处通知客户端进入idle状态(也就是不那么忙了)。这时候ActivityStack.activityIdleInternalLocked()函数就会处理之前被pause的activity的其他生命周期,如Activity.onStop(),Activity.onDestory()。 当然客户端这边也许很久才会进入idle状态(一定是一个比较差劲的开发者写了糟糕的代码),这时候就会触发IDLE_TIMEOUT消息, DLE_TIMEOUT消息的处理函数同样会调用ActivityStack.activityIdleInternalLocked()函数来执行被pause的activity后续生命周期方法。 还有一种情况需要马上执行Activity的onStop(),onDestory()等生命周期函数, 这时候发送一条IDLE_NOW消息,IDLE_NOW消息的处理函数同样会调用ActivityStack.activityIdleInternalLocked()函数来执行被pause的activity后续生命周期方法。

其实Activity生命周期相互作用的函数就onResume和onPause,这两个函数要保证时序,其他的都没有影响。

下面我们从代码来详细分析.
从ActivityManagerService对于Task的管理这篇文章我们知道Ams使用ActivityStack类管理返回栈。 使用ActivityStackSupervisor 管理多个ActivityStack,所以Activity的启动也是先经过ActivityStackSupervisor来确定启动在哪个栈上的。主要的函数就是startActivityUncheckedLocked函数。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

    final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,boolean doResume, Bundle options, TaskRecord inTask) {........ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);targetStack.mLastPausedActivity = null;targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);......
}

startActivityUncheckedLocked 函数的逻辑其实我在ActivityManagerService->Activity启动->任务选择和Activity复用(Android 6.0) 一文中基本说明过。到了调用targetStack.startActivityLocked这一步已经代要启动一个新的Activity了。

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

2074     final void startActivityLocked(ActivityRecord r, boolean newTask,
2075             boolean doResume, boolean keepCurTransition, Bundle options) {2076         TaskRecord rTask = r.task;
2077         final int taskId = rTask.taskId;
2078         // mLaunchTaskBehind tasks get placed at the back of the task stack.
2079         if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {// 需要的情况把要启动的Activity对应的Task放到stack的顶部,对应把Wms侧的Task也放到栈顶
2080             // Last activity in task had been removed or ActivityManagerService is reusing task.
2081             // Insert or replace.
2082             // Might not even be in.
2083             insertTaskAtTop(rTask, r);
2084             mWindowManager.moveTaskToTop(taskId);
2085         }
2086         TaskRecord task = null;
2087         if (!newTask) {// 对于不是新创建的Task,判断要启动的Activity对应的Task上面是否还有其他的Task有全屏的Activity。// 如果有的话代表要启动的Activity对应的Task会被遮挡,也就不需要启动了, // 这里把ActivityRecord移动的Task顶即可,当需要显示它的时候再启动。 同样也把AppToken添加到Wms侧的// task上。
2088             // If starting in an existing task, find where that is...
2089             boolean startIt = true;
2090             for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {2091                 task = mTaskHistory.get(taskNdx);
2092                 if (task.getTopActivity() == null) {2093                     // All activities in task are finishing.
2094                     continue;
2095                 }
2096                 if (task == r.task) {2097                     // Here it is!  Now, if this is not yet visible to the
2098                     // user, then just add it without starting; it will
2099                     // get started when the user navigates back to it.
2100                     if (!startIt) {2101                         if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
2102                                 + task, new RuntimeException("here").fillInStackTrace());
2103                         task.addActivityToTop(r);
2104                         r.putInHistory();
2105                         mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
2106                                 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
2107                                 (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
2108                                 r.userId, r.info.configChanges, task.voiceSession != null,
2109                                 r.mLaunchTaskBehind);
2110                         if (VALIDATE_TOKENS) {2111                             validateAppTokensLocked();
2112                         }
2113                         ActivityOptions.abort(options);
2114                         return;
2115                     }
2116                     break;
2117                 } else if (task.numFullscreen > 0) {2118                     startIt = false;
2119                 }
2120             }
2121         }
2122
2123         // Place a new activity at top of stack, so it is next to interact
2124         // with the user.
2125
2126         // If we are not placing the new activity frontmost, we do not want
2127         // to deliver the onUserLeaving callback to the actual frontmost
2128         // activity
2129         if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {2130             mStackSupervisor.mUserLeaving = false;
2131             if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2132                     "startActivity() behind front, mUserLeaving=false");
2133         }
2134
2135         task = r.task;
2136
2137         // Slot the activity into the history stack and proceed
2138         if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
2139                 new RuntimeException("here").fillInStackTrace());
2140         task.addActivityToTop(r);
2141         task.setFrontOfTask();
2142
2143         r.putInHistory();
2144         if (!isHomeStack() || numActivities() > 0) { // 非HomeStack的清空(非桌面Activity和最近任务Activit)......// 设置切换动画类型......2173             boolean doShow = true;
2174             if (newTask) {2175                 // Even though this activity is starting fresh, we still need
2176                 // to reset it to make sure we apply affinities to move any
2177                 // existing activities from other tasks in to it.
2178                 // If the caller has requested that the target task be
2179                 // reset, then do so.
2180                 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {// 如果reset task把要启动的Activity清掉或者从Task顶部移除则不需要显示该要启动的Activity
2181                     resetTaskIfNeededLocked(r, r);
2182                     doShow = topRunningNonDelayedActivityLocked(null) == r;
2183                 }
2184             } else if (options != null && new ActivityOptions(options).getAnimationType()
2185                     == ActivityOptions.ANIM_SCENE_TRANSITION) {// ANIM_SCENE_TRANSITION类型的切换动画不需要马上显示要启动的Activity
2186                 doShow = false;
2187             }......// 设置startingwindow相关......
2218         } else {2219             // If this is the first activity, don't do any fancy animations,
2220             // because there is nothing for it to animate on top of.// 桌面或者最近任务Activity,不需要设置动画
2221             mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
2222                     r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
2223                     (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
2224                     r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
2225             ActivityOptions.abort(options);
2226             options = null;
2227         }
2228         if (VALIDATE_TOKENS) {2229             validateAppTokensLocked();
2230         }
2231
2232         if (doResume) {// 需要显示的Activity的情况调用resumeTopActivitiesLocked来恢复焦点栈Activity
2233             mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
2234         }
2235     }

startActivityLocked函数主要判断是否要启动,对于要启动的Activity设置切换动画,设置starting window。最后对真的要显示的Activity执行mStackSupervisor.resumeTopActivitiesLocked(this, r, options)来将Activity设置成resumeActivity状态。注意resumeTopActivitiesLocked函数的名字是remumeTopActivitiesLocked,并不是start某Activity,而是要显示某个Activity,这也说明该函数的调用路径是有新的Activity启动,需要设置为栈顶的Activity为resumed状态,也可能是某个Activity关闭需要设置下面的Activity为resumed状态。所以分析该函数的时候要分这两种情况去分析。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

2727     boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2728             Bundle targetOptions) {2729         if (targetStack == null) {2730             targetStack = mFocusedStack;
2731         }
2732         // Do targetStack first.
2733         boolean result = false;
2734         if (isFrontStack(targetStack)) {2735             result = targetStack.resumeTopActivityLocked(target, targetOptions);
2736         }
2737
2738         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {2739             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2740             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {2741                 final ActivityStack stack = stacks.get(stackNdx);
2742                 if (stack == targetStack) {2743                     // Already started above.
2744                     continue;
2745                 }
2746                 if (isFrontStack(stack)) {2747                     stack.resumeTopActivityLocked(null);
2748                 }
2749             }
2750         }
2751         return result;
2752     }

resumeTopActivitiesLocked函数如果参数中没指定目标stack则使用焦点stack来作为候选stack,否则使用参数的stack作为候选stack。 2735如果候选stack 是焦点stack则调用stack的resumeTopActivityLocked来设置栈顶Activity状态到resumed。这里有可能候选stack不是焦点stack,则2738-2750行遍历所有屏幕上的stack,找到焦点stack来恢复焦点stack的栈顶activity到remued状态。这个遍历感觉有点多此一举。 这里我们可以知道焦点stack只有一个,就像我们的pc机桌面,同时只能操作一个窗口,某人的键盘事件会发给该窗口。

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {if (mStackSupervisor.inResumeTopActivity) {// Don't even start recursing.return false;}boolean result = false;try {// Protect against recursion.mStackSupervisor.inResumeTopActivity = true;if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;mService.updateSleepIfNeededLocked();}result = resumeTopActivityInnerLocked(prev, options);} finally {mStackSupervisor.inResumeTopActivity = false;}return result;}

这里通过mStackSupervisor.inResumeTopActivity 参数,防止两个参数的resumeTopActivityInnerLocked函数嵌套调用。
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

1561     private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {// prev可能是要关闭的Activity,也可能是要启动的Activity。......
1576         // 删除栈顶要恢复的Activity下面所有不需要的staring window
1577         cancelInitializingActivities();
1578 // 获取要resume的activity,记住next为要设置状态为resmued的Activity。
1579         // Find the first activity that is not finishing.
1580         final ActivityRecord next = topRunningActivityLocked(null);
1581
1582         // Remember how we'll process this pause/resume situation, and ensure
1583         // that the state is reset however we wind up proceeding.
1584         final boolean userLeaving = mStackSupervisor.mUserLeaving;
1585         mStackSupervisor.mUserLeaving = false;
1586
1587         final TaskRecord prevTask = prev != null ? prev.task : null;
1588         if (next == null) { // stack上已经没有可以设置为resmued的Activity
1589             // There are no more activities!
1590             final String reason = "noMoreActivities";
1591             if (!mFullscreen) {1592                 // Try to move focus to the next visible stack with a running activity if this
1593                 // stack is not covering the entire screen.// 分屏的情况这个stack上没有可显示的Activity,找到其他可见的stack设置为焦点Stack来显示上面的//Activity(设置为resumed状态)。
1594                 final ActivityStack stack = getNextVisibleStackLocked();
1595                 if (adjustFocusToNextVisibleStackLocked(stack, reason)) {1596                     return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null);
1597                 }
1598             }
1599             // Let's just start up the Launcher...
1600             ActivityOptions.abort(options);
1601             if (DEBUG_STATES) Slog.d(TAG_STATES,
1602                     "resumeTopActivityLocked: No more activities go home");
1603             if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1604             // Only resume home if on home display
1605             final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
1606                     HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();// 全屏焦点stack上没有可设置为resumed状态的Activity, 如果是Home display上可以启动桌面,设置// HomeStack为焦点stack,设置HomeStack栈顶的Activity为resmued状态。// 否则返回false,表示没有真正执行resume activity
1607             return isOnHomeDisplay() &&
1608                     mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
1609         }
1610
1611         next.delayedResume = false;
1612
1613         // If the top activity is the resumed one, nothing to do.
1614         if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
1615                     mStackSupervisor.allResumedActivitiesComplete()) {// 要resume的Activity已经是RESUMED状态则不需要做什么了,返回false,// 表示没有真正执行resume activity
1616             // Make sure we have executed any pending transitions, since there
1617             // should be nothing left to do at this point.
1618             mWindowManager.executeAppTransition();
1619             mNoAnimActivities.clear();
1620             ActivityOptions.abort(options);
1621             if (DEBUG_STATES) Slog.d(TAG_STATES,
1622                     "resumeTopActivityLocked: Top activity resumed " + next);
1623             if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1624             return false;
1625         }
1626
1627         final TaskRecord nextTask = next.task;
1628         if (prevTask != null && prevTask.stack == this &&
1629                 prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {// 关闭Activity的分支,并且关闭Activity返回到桌面
1630             if (DEBUG_STACK)  mStackSupervisor.validateTopActivitiesLocked();
1630             if (DEBUG_STACK)  mStackSupervisor.validateTopActivitiesLocked();
1631             if (prevTask == nextTask) {// 关闭的Activity上还有其他Activity,所以并不能返回到桌面,// 设置其他Activity作为task的front activity。
1632                 prevTask.setFrontOfTask();
1633             } else if (prevTask != topTask()) {1634                 // This task is going away but it was supposed to return to the home stack.
1635                 // Now the task above it has to return to the home task instead.// 要关闭的Task上面还有其他Task,设置其他task的关闭后返回到桌面
1636                 final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
1637                 mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1638             } else if (!isOnHomeDisplay()) {// 由于其他display上不能启动桌面stack,所以直接返回
1639                 return false;
1640             } else if (!isHomeStack()){1641                 if (DEBUG_STATES) Slog.d(TAG_STATES,
1642                         "resumeTopActivityLocked: Launching home next");
1643                 final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
1644                         HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();// 恢复桌面stack
1645                 return isOnHomeDisplay() &&
1646                         mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
1647             }
1648         }
1649 ......1676         // The activity may be waiting for stop, but that is no longer
1677         // appropriate for it.// 要设置next为resumed状态,所以从mStoppingActivities,// mGoingToSleepActivities和mWaitingVisibleActivities中删除next。 // mStoppingActivities表示要设置为stoped的Activity,但是还没有请求客户端执行。 // 一般要等到栈顶Activity为idle状态才会设置被覆盖的Activity为stop状态,防止cpu争用。// mGoingToSleepActivities 表示已经请求应用程序// ActivityThread来stop该Activity,ActivityThread还没有stop完成的Activity。// mWaitingVisibleActivities 表示要等待其他Activity可见来执行一些操作的Activity。
1678         mStackSupervisor.mStoppingActivities.remove(next);
1679         mStackSupervisor.mGoingToSleepActivities.remove(next);
1680         next.sleeping = false;
1681         mStackSupervisor.mWaitingVisibleActivities.remove(next);
1682
1683         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
1684
1685         // If we are currently pausing an activity, then don't do anything
1686         // until that is done.
1687         if (!mStackSupervisor.allPausedActivitiesComplete()) {// 如果有其他Activity正在要进入paused状态,那么先等待其他Activity进入paused状态再来恢复焦点栈上的// Activity。
1688             if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
1689                     "resumeTopActivityLocked: Skip resume: some activity pausing.");
1690             if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1691             return false;
1692         }
1693 ......1725         // We need to start pausing the current activity so the top one
1726         // can be resumed...// 因为系统同时只有一个焦点stack上的Activity可以作为焦点Activity为resumed状态,所以这里先把其他// stack上的resumed状态的Activity设置为paused, 再把焦点栈上的Activity设置为paused状态。
1727         boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
1728         boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
1729         if (mResumedActivity != null) {1730             if (DEBUG_STATES) Slog.d(TAG_STATES,
1731                     "resumeTopActivityLocked: Pausing " + mResumedActivity);
1732             pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
1733         }
1734         if (pausing) {// 有Activity正在进入pause状态则等待pause完成,再来恢复焦点栈上Activity,这里直接返回了。
1735             if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
1736                     "resumeTopActivityLocked: Skip resume: need to start pausing");
1737             // At this point we want to put the upcoming activity's process
1738             // at the top of the LRU list, since we know we will be needing it
1739             // very soon and it would be a waste to let it get killed if it
1740             // happens to be sitting towards the end.
1741             if (next.app != null && next.app.thread != null) {1742                 mService.updateLruProcessLocked(next.app, true, null);
1743             }
1744             if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1745             return true;
1746         }......
2012     }

resumeTopActivityInnerLocked代码比较长我们先分析前半部分, 前半部分主要检查stack上Activity恢复的可行性,不可行的情况要么直接返回了,要么就在其他stack上恢复了Activity返回。 经过检查后确定就要恢复当前stack上的Activity,在恢复Activity前如果发现当前stack还有resumed状态的Activity,要先将这个Activity设置成paused状态才能恢复Activity。 将resumed的Activity设置成paused状态调用的是startPausingLocked函数,我们先来分析startPausingLocked,后面再来看resumeTopActivityInnerLocked函数的后半部分(真正将Activity设置到resumed状态的代码)。

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

 802     /**803      * Start pausing the currently resumed activity.  It is an error to call this if there804      * is already an activity being paused or there is no resumed activity.805      *806      * @param userLeaving True if this should result in an onUserLeaving to the current activity.807      * @param uiSleeping True if this is happening with the user interface going to sleep (the808      * screen turning off).809      * @param resuming True if this is being called as part of resuming the top activity, so810      * we shouldn't try to instigate a resume here.811      * @param dontWait True if the caller does not want to wait for the pause to complete.  If812      * set to true, we will immediately complete the pause here before returning.813      * @return Returns true if an activity now is in the PAUSING state, and we are waiting for814      * it to tell us when it is done.815      */816     final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,817             boolean dontWait) {......828         ActivityRecord prev = mResumedActivity;......// 设置 mResumedActivity为空。代表当前stack没有resumed状态的Activity.844         mResumedActivity = null;// mPausingActivity 为prev,表示正在pause的Activity845         mPausingActivity = prev;846         mLastPausedActivity = prev;847         mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0848                 || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;849         prev.state = ActivityState.PAUSING;850         prev.task.touchActiveTime();851         clearLaunchTime(prev);852         final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();853         if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {854             prev.updateThumbnailLocked(screenshotActivities(prev), null);855         }856         stopFullyDrawnTraceIfNeeded();857 858         mService.updateCpuStats();859 860         if (prev.app != null && prev.app.thread != null) {// Activity对应的进程还在, 调用ActivityThread.schedulePauseActivity()方法请求客户端将// Activity设置成pause状态。861             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);862             try {863                 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,864                         prev.userId, System.identityHashCode(prev),865                         prev.shortComponentName);866                 mService.updateUsageStats(prev, false);867                 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,868                         userLeaving, prev.configChangeFlags, dontWait);869             } catch (Exception e) {870                 // Ignore exception, if process died other code will cleanup.871                 Slog.w(TAG, "Exception thrown during pause", e);872                 mPausingActivity = null;873                 mLastPausedActivity = null;874                 mLastNoHistoryActivity = null;875             }876         } else {// Activity对应的进程不存在,表示pause成功877             mPausingActivity = null;878             mLastPausedActivity = null;879             mLastNoHistoryActivity = null;880         }881 882         // If we are not going to sleep, we want to ensure the device is883         // awake until the next activity is started.884         if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {885             mStackSupervisor.acquireLaunchWakelock();886         }887 888         if (mPausingActivity != null) {889             // Have the window manager pause its key dispatching until the new890             // activity has started.  If we're pausing the activity just because891             // the screen is being turned off and the UI is sleeping, don't interrupt892             // key dispatch; the same activity will pick it up again on wakeup.893             if (!uiSleeping) {894                 prev.pauseKeyDispatchingLocked();895             } else if (DEBUG_PAUSE) {896                  Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");897             }898 899             if (dontWait) {900                 // If the caller said they don't want to wait for the pause, then complete901                 // the pause now.// 不需要等待客户端完成pause,直接执行completePauseLocked表示Activity的pause已经完成。902                 completePauseLocked(false);903                 return false;904 905             } else {// 需要等待客户端pause完成,发送一个超时消息,防止客户端bug。906                 // Schedule a pause timeout in case the app doesn't respond.907                 // We don't give it much time because this directly impacts the908                 // responsiveness seen by the user.909                 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);910                 msg.obj = prev;911                 prev.pauseTime = SystemClock.uptimeMillis();912                 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);913                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");914                 return true;915             }916 917         } else {918             // This activity failed to schedule the919             // pause, so just treat it as being paused now.920             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");921             if (!resuming) {// 如果不是resuming流程,那么恢复焦点task上的Activity可见922                 mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);923             }// 没有pausing状态的Activity,返回false。924             return false;925         }926     }

startPausingLocked函数用于将stack中resumed状态的Activity(也就是mResumedActivity)设置为paused状态,我们都知道Activity的生命周期方法onPause,其实这个过程就是调用Activity的onPause方法。 所以这里通过调用ActivityThread的binder代理对象来完成,也就是887行代码。887行代码的第一个参数为appToken,通过这个token就可以在应用测找到对应的Activity。
899-904行如果不需要等待客户端完成activity的pause操作,则直接调用completePauseLocked函数来处理Activity pause完成的状态,返回false,表示pause已经完成。906到914行需要等待客户端pause完成,这时候客户端是不可靠的,可能由于某种bug不会通告Ams要pause的Activity已经完成,所以设置一个超时事件,客户端不反馈的话就按照pause完成来处理。最终都是调用completePauseLocked函数来完成Activity的pause处理。
我们来看看应用端的处理
frameworks/base/core/java/android/app/ActivityThread.java

        public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) {sendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,token,(userLeaving ? 1 : 0) | (dontReport ? 2 : 0),configChanges);}

这里发送一个PAUSE_ACTIVITY消息给Android进程的主线程来处理Activity pause事件。
frameworks/base/core/java/android/app/ActivityThread.java

    private void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) {ActivityClientRecord r = mActivities.get(token);......performPauseActivity(token, finished, r.isPreHoneycomb());......// Tell the activity manager we have paused.if (!dontReport) {try {ActivityManagerNative.getDefault().activityPaused(token);} catch (RemoteException ex) {}}}}

应用端这测调用performPauseActivity函数来执行Activity.onPause 函数,然后调用ActivityManagerNative.getDefault().activityPaused(token)函数来通知Ams端Activity已经进入到paused状态。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    @Overridepublic final void activityPaused(IBinder token) {final long origId = Binder.clearCallingIdentity();synchronized(this) {ActivityStack stack = ActivityRecord.getStackLocked(token);if (stack != null) {stack.activityPausedLocked(token, false);}}Binder.restoreCallingIdentity(origId);}

找到Activity对应的stack,调用对用stack的activityPausedLocked方法。
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

 928     final void activityPausedLocked(IBinder token, boolean timeout) {929         if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,930             "Activity paused: token=" + token + ", timeout=" + timeout);931 932         final ActivityRecord r = isInStackLocked(token);933         if (r != null) {934             mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);935             if (mPausingActivity == r) {936                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r937                         + (timeout ? " (due to timeout)" : " (pause complete)"));938                 completePauseLocked(true);939             } else {940                 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,941                         r.userId, System.identityHashCode(r), r.shortComponentName,942                         mPausingActivity != null943                             ? mPausingActivity.shortComponentName : "(none)");944                 if (r.finishing && r.state == ActivityState.PAUSING) {945                     if (DEBUG_PAUSE) Slog.v(TAG,946                             "Executing finish of failed to pause activity: " + r);947                     finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);948                 }949             }950         }951     }

activityPausedLocked函数有两个参数, 第一个参数token代表Activity的身份,通过token可以找到Ams对应的Activity 存根ActivityRecord, 第二个参数代表动用函数的原因,如果参数timeout为真表示activityPausedLocked函数是由于PAUSE_TIMEOUT消息触发的,客户端pause activity超时。 否则为客户端上报Activity pause完成。 代码934行首先清除该ActivityRecord对应的超时消息。然后判断mPausingActivity是否为参数token对应的Activity。 如果不是的话说明不是Ams端主动调用的Activity pause, 不需要处理pause activity完成,也就是说不需指定completePauseLocked,也可能是客户端别有意图的调用,如果这个Activity需要关闭则调用finishCurrentActivityLocked来执行Activity的后续生命周期。 completePauseLocked函数来处理Activity的pause状态完成。

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

994     private void completePauseLocked(boolean resumeNext) {995         ActivityRecord prev = mPausingActivity;996         if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);997 998         if (prev != null) {999             prev.state = ActivityState.PAUSED;
1000             if (prev.finishing) {1001                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);// Activity需要关闭的情况调用finishCurrentActivityLocked,注意这里不一定马上关闭Activity,// 可能需要等待要启动的Activity进入idle状态再去执行Activity的后续生命周期方法
1002                 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
1003             } else if (prev.app != null) {......
1009                 if (prev.configDestroy) {1010                     // The previous is being paused because the configuration
1011                     // is changing, which means it is actually stopping...
1012                     // To juggle the fact that we are also starting a new
1013                     // instance right now, we need to first completely stop
1014                     // the current instance before starting the new one.// 如果Activity的config发生变化,先销毁它准备重启
1015                     if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Destroying after pause: " + prev);
1016                     destroyActivityLocked(prev, true, "pause-config");
1017                 } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {1018                     // If we were visible then resumeTopActivities will release resources before
1019                     // stopping.// 将Activity添加到mStoppingActivities中等待要启动的Activity进入idle状态后再// 执行Activity的后续onStop生命周期。 默认情况下是等到要进入resumed状态的Activity// 进入到idle状态后再去调用前边Activity的onStop和onDestoy等生命周期函数。
1020                     mStackSupervisor.mStoppingActivities.add(prev);
1021                     if (mStackSupervisor.mStoppingActivities.size() > 3 ||
1022                             prev.frontOfTask && mTaskHistory.size() <= 1) {// 这里检查如果等待执行stop生命周期的Activity超过// 3个或者该Activity是stack中最后一个task上的最后一个Activity,执行scheduleIdleLocked尽快// 处理Activity的后续生命周期方法。
1023                         // If we already have a few activities waiting to stop,
1024                         // then give up on things going idle and start clearing
1025                         // them out. Or if r is the last of activity of the last task the stack
1026                         // will be empty and must be cleared immediately.
1027                         if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "To many pending stops, forcing idle");// 发送IDLE_NOW_MSG消息
1028                         mStackSupervisor.scheduleIdleLocked();
1029                     } else {// 检查是否由于其他情况需要提前执行Activity的onStop等生命周期方法
1030                         mStackSupervisor.checkReadyForSleepLocked();
1031                     }
1032                 }
1033             } else {1034                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
1035                 prev = null;
1036             }
1037             // It is possible the activity was freezing the screen before it was paused.
1038             // In that case go ahead and remove the freeze this activity has on the screen
1039             // since it is no longer visible.
1040             prev.stopFreezingScreenLocked(true /*force*/);
1041             mPausingActivity = null;
1042         }
1043
1044         if (resumeNext) {// 需要恢复下一个Activity的情况调用mStackSupervisor.resumeTopActivitiesLocked(// topStack, prev, null)函数,来恢复焦点栈上顶部Activity到resumed状态,// resumeTopActivitiesLocked这个函数前边我们分析过,最终调用到ActivityStack的// resumeTopActivitiesLocked方法1045             final ActivityStack topStack = mStackSupervisor.getFocusedStack();
1046             if (!mService.isSleepingOrShuttingDown()) {1047                 mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
1048             } else {1049                 mStackSupervisor.checkReadyForSleepLocked();
1050                 ActivityRecord top = topStack.topRunningActivityLocked(null);
1051                 if (top == null || (prev != null && top != prev)) {1052                     // If there are no more activities available to run,
1053                     // do resume anyway to start something.  Also if the top
1054                     // activity on the stack is not the just paused activity,
1055                     // we need to go ahead and resume it to ensure we complete
1056                     // an in-flight app switch.
1057                     mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
1058                 }
1059             }
1060         }......
1086     }

completePauseLocked函数处理Activity完成pause的后续状态,会将paused状态的Activity添加到mStoppingActivities这个集合中,等待合适的时机来执行Activity的后续生命周期方法,本文一开始已经说明一般要等到要resume的Activity进程进入idle状态后再执行该Activity的onStop和onPuase方法,以免造成cpu的争抢。但是这里还是有些特殊的情况。 比如1021-1028行代码,当等待执行stop的Activity超过三个的时候,或者stack中最后一个Activity的时候。 另外ActivityStackSupervisor.checkReadyForSleepLocked函数也会检查一些情况,提前执行Activity的onStop等后续生命周期。 最后需要resume activity的情况调用mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null)函数来恢复焦点栈上的Activity。ActivityStackSupervisor的resumeTopActivitiesLocked这个函数前边我们分析过,最终调用到ActivityStack的
resumeTopActivitiesLocked方法,我们前面分析了一半ActivityStack.resumeTopActivitiesLocked方法,后面继续分析另一半

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

1561     private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {......// 设置相关动画1859         ActivityStack lastStack = mStackSupervisor.getLastStack();
1860         if (next.app != null && next.app.thread != null) {// Activity已经启动的情况next.app不为空
1861             if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next);
1862
1863             // This activity is now becoming visible.
1864             mWindowManager.setAppVisibility(next.appToken, true);
1865
1866             // schedule launch ticks to collect information about slow apps.
1867             next.startLaunchTickingLocked();
1868
1869             ActivityRecord lastResumedActivity =
1870                     lastStack == null ? null :lastStack.mResumedActivity;
1871             ActivityState lastState = next.state;
1872
1873             mService.updateCpuStats();
1874
1875             if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");
1876             next.state = ActivityState.RESUMED;
1877             mResumedActivity = next;
1878             next.task.touchActiveTime();
1879             mRecentTasks.addLocked(next.task);
1880             mService.updateLruProcessLocked(next.app, true, null);
1881             updateLRUListLocked(next);
1882             mService.updateOomAdjLocked();
1883 // 根据新的焦点Activity更新configuration
1884             // Have the window manager re-evaluate the orientation of
1885             // the screen based on the new activity order.
1886             boolean notUpdated = true;
1887             if (mStackSupervisor.isFrontStack(this)) {1888                 Configuration config = mWindowManager.updateOrientationFromAppTokens(
1889                         mService.mConfiguration,
1890                         next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
1891                 if (config != null) {1892                     next.frozenBeforeDestroy = true;
1893                 }
1894                 notUpdated = !mService.updateConfigurationLocked(config, next, false, false);
1895             }
1896
1897             if (notUpdated) {// 由于配置更新导致Activity需要重新启动,计算下一个需要显示的Activity,调用// scheduleResumeTopActivities 来进行恢复。否则返回false。
1898                 // The configuration update wasn't able to keep the existing
1899                 // instance of the activity, and instead started a new one.
1900                 // We should be all done, but let's just make sure our activity
1901                 // is still at the top and schedule another run if something
1902                 // weird happened.
1903                 ActivityRecord nextNext = topRunningActivityLocked(null);
1904                 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
1905                         "Activity config changed during resume: " + next
1906                         + ", new next: " + nextNext);
1907                 if (nextNext != next) {1908                     // Do over!
1909                     mStackSupervisor.scheduleResumeTopActivities();
1910                 }
1911                 if (mStackSupervisor.reportResumedActivityLocked(next)) {1912                     mNoAnimActivities.clear();
1913                     if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1914                     return true;
1915                 }
1916                 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1917                 return false;
1918             }
1919
1920             try {1921                 // Deliver all pending results.
1922                 ArrayList<ResultInfo> a = next.results;
1923                 if (a != null) {// 发送结果
1924                     final int N = a.size();
1925                     if (!next.finishing && N > 0) {1926                         if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
1927                                 "Delivering results to " + next + ": " + a);
1928                         next.app.thread.scheduleSendResult(next.appToken, a);
1929                     }
1930                 }
1931
1932                 if (next.newIntents != null) {// 发送新intent
1933                     next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
1934                 }
1935
1936                 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
1937                         System.identityHashCode(next), next.task.taskId, next.shortComponentName);
1938
1939                 next.sleeping = false;
1940                 mService.showAskCompatModeDialogLocked(next);
1941                 next.app.pendingUiClean = true;
1942                 next.app.forceProcessStateUpTo(mService.mTopProcessState);
1943                 next.clearOptionsLocked();// 调用ActivityThread将Activity弄到resumed状态(因为Activity已经启动了)
1944                 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
1945                         mService.isNextTransitionForward(), resumeAnimOptions);
1946
1947                 mStackSupervisor.checkReadyForSleepLocked();
1948
1949                 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next);
1950             } catch (Exception e) {1951                 // Whoops, need to restart this activity!
1952                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
1953                         + lastState + ": " + next);
1954                 next.state = lastState;
1955                 if (lastStack != null) {1956                     lastStack.mResumedActivity = lastResumedActivity;
1957                 }
1958                 Slog.i(TAG, "Restarting because process died: " + next);
1959                 if (!next.hasBeenLaunched) {1960                     next.hasBeenLaunched = true;
1961                 } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
1962                         mStackSupervisor.isFrontStack(lastStack)) {1963                     mWindowManager.setAppStartingWindow(
1964                             next.appToken, next.packageName, next.theme,
1965                             mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
1966                             next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
1967                             next.windowFlags, null, true);
1968                 }// 异常了重新启动该Activity
1969                 mStackSupervisor.startSpecificActivityLocked(next, true, false);
1970                 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1971                 return true;
1972             }
1973
1974             // From this point on, if something goes wrong there is no way
1975             // to recover the activity.
1976             try {1977                 next.visible = true;// completeResumeLocked 完成resume activity的处理
1978                 completeResumeLocked(next);
1979             } catch (Exception e) {1980                 // If any exception gets thrown, toss away this
1981                 // activity and try the next one.
1982                 Slog.w(TAG, "Exception thrown during resume of " + next, e);
1983                 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
1984                         "resume-exception", true);
1985                 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1986                 return true;
1987             }
1988             next.stopped = false;
1989
1990         } else {// Activity 还没有启动,调用mStackSupervisor.startSpecificActivityLocked(next, true, true)正式// 启动Activity
1991             // Whoops, need to restart this activity!
1992             if (!next.hasBeenLaunched) {1993                 next.hasBeenLaunched = true;
1994             } else {1995                 if (SHOW_APP_STARTING_PREVIEW) {1996                     mWindowManager.setAppStartingWindow(
1997                             next.appToken, next.packageName, next.theme,
1998                             mService.compatibilityInfoForPackageLocked(
1999                                     next.info.applicationInfo),
2000                             next.nonLocalizedLabel,
2001                             next.labelRes, next.icon, next.logo, next.windowFlags,
2002                             null, true);
2003                 }
2004                 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
2005             }
2006             if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
2007             mStackSupervisor.startSpecificActivityLocked(next, true, true);
2008         }
2009
2010         if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2011         return true;
2012     }

resumeTopActivityInnerLocked函数有两大分支,分别是Activity已经启动,恢复到resumed状态即可,该分支调用ActivityThread.scheduleResumeActivity 函数来执行Activity的生命周期方法到Activity的resumed状态。 第二个分支调用StackSupervisor.startSpecificActivityLocked函数来启动Activity。 无论那个分支,最终Activity到resumed状态后都会调用completeResumeLocked函数来处理Activity进入resumed状态完成。

1088     /**
1089      * Once we know that we have asked an application to put an activity in
1090      * the resumed state (either by launching it or explicitly telling it),
1091      * this function updates the rest of our state to match that fact.
1092      */
1093     private void completeResumeLocked(ActivityRecord next) {......
1109 // 设置IDLE超时消息,防止客户端一直不进入idle状态,等待stop的Activity无法回掉Activity的onStop方法。
1110         // schedule an idle timeout in case the app doesn't do it for us.
1111         mStackSupervisor.scheduleIdleTimeoutLocked(next);......
1133     }
1134 void scheduleIdleTimeoutLocked(ActivityRecord next) {if (DEBUG_IDLE) Slog.d(TAG_IDLE,"scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);}

这里设置了一个等待Activity idle超时的消息。 我们前面说过Activity进入idle状态,或者IDLE_TIMEOUT,或者IDLE_NOW_MSG消息都会触发需要stop的activity的后续生命周期方法。 IDLE_TIMEOUT和 IDLE_NOW_MSG消息的发送我们前面都看到了。再来分析下应用何时进入IDLE状态。
frameworks/base/core/java/android/app/ActivityThread.java

    final void handleResumeActivity(IBinder token,boolean clearHide, boolean isForward, boolean reallyResume) {// If we are getting ready to gc after going to the background, well......Looper.myQueue().addIdleHandler(new Idler());......

在调用完Activity的onResume方法后会向应用主线程对应的MessageQueue中添加一个IdleHandler。
frameworks/base/core/java/android/os/MessageQueue.java

    /*** Add a new {@link IdleHandler} to this message queue.  This may be* removed automatically for you by returning false from* {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is* invoked, or explicitly removing it with {@link #removeIdleHandler}.** <p>This method is safe to call from any thread.** @param handler The IdleHandler to be added.*/public void addIdleHandler(@NonNull IdleHandler handler) {if (handler == null) {throw new NullPointerException("Can't add a null IdleHandler");}synchronized (this) {mIdleHandlers.add(handler);}}
   307     Message next() {308         // Return here if the message loop has already quit and been disposed.
309         // This can happen if the application tries to restart a looper after quit
310         // which is not supported.
311         final long ptr = mPtr;
312         if (ptr == 0) {313             return null;
314         }
315
316         int pendingIdleHandlerCount = -1; // -1 only during first iteration
317         int nextPollTimeoutMillis = 0;
318         for (;;) {319             if (nextPollTimeoutMillis != 0) {320                 Binder.flushPendingCommands();
321             }
322
323             nativePollOnce(ptr, nextPollTimeoutMillis);
324
325             synchronized (this) {326                 // Try to retrieve the next message.  Return if found.
327                 final long now = SystemClock.uptimeMillis();
328                 Message prevMsg = null;
329                 Message msg = mMessages;
330                 if (msg != null && msg.target == null) {331                     // Stalled by a barrier.  Find the next asynchronous message in the queue.
332                     do {333                         prevMsg = msg;
334                         msg = msg.next;
335                     } while (msg != null && !msg.isAsynchronous());
336                 }
337                 if (msg != null) {338                     if (now < msg.when) {339                         // Next message is not ready.  Set a timeout to wake up when it is ready.
340                         nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
341                     } else {342                         // Got a message.
343                         mBlocked = false;
344                         if (prevMsg != null) {345                             prevMsg.next = msg.next;
346                         } else {347                             mMessages = msg.next;
348                         }
349                         msg.next = null;
350                         if (DEBUG) Log.v(TAG, "Returning message: " + msg);
351                         msg.markInUse();
352                         return msg;
353                     }
354                 } else {355                     // No more messages.
356                     nextPollTimeoutMillis = -1;
357                 }
358
359                 // Process the quit message now that all pending messages have been handled.
360                 if (mQuitting) {361                     dispose();
362                     return null;
363                 }
364
365                 // If first time idle, then get the number of idlers to run.
366                 // Idle handles only run if the queue is empty or if the first message
367                 // in the queue (possibly a barrier) is due to be handled in the future.
368                 if (pendingIdleHandlerCount < 0
369                         && (mMessages == null || now < mMessages.when)) {370                     pendingIdleHandlerCount = mIdleHandlers.size();
371                 }
372                 if (pendingIdleHandlerCount <= 0) {373                     // No idle handlers to run.  Loop and wait some more.
374                     mBlocked = true;
375                     continue;
376                 }
377
378                 if (mPendingIdleHandlers == null) {379                     mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
380                 }
381                 mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
382             }
383
384             // Run the idle handlers.
385             // We only ever reach this code block during the first iteration.
386             for (int i = 0; i < pendingIdleHandlerCount; i++) {387                 final IdleHandler idler = mPendingIdleHandlers[i];
388                 mPendingIdleHandlers[i] = null; // release the reference to the handler
389
390                 boolean keep = false;
391                 try {392                     keep = idler.queueIdle();
393                 } catch (Throwable t) {394                     Log.wtf(TAG, "IdleHandler threw exception", t);
395                 }
396
397                 if (!keep) {398                     synchronized (this) {399                         mIdleHandlers.remove(idler);
400                     }
401                 }
402             }
403
404             // Reset the idle handler count to 0 so we do not run them again.
405             pendingIdleHandlerCount = 0;
406
407             // While calling an idle handler, a new message could have been delivered
408             // so go back and look again for a pending message without waiting.
409             nextPollTimeoutMillis = 0;
410         }
411     }

MessageQueue的next()方法获取MessageQueue中的消息,如果没有马上要处理的消息就会执行308-403行代码。这段代码找到注册到系统中的mIdleHandlers调用它的queueIdle方法。
我们关注的IdleHandler是Activity的Idler,对应的MessageQueue为应用主线程的MessageQueue,也就是说等到应用主线程闲下来的时候调用Idler.queueIdle()方法。所以看下Idler如何处理吧。
frameworks/base/core/java/android/app/ActivityThread.java

private class Idler implements MessageQueue.IdleHandler {@Overridepublic final boolean queueIdle() {ActivityClientRecord a = mNewActivities;boolean stopProfiling = false;if (mBoundApplication != null && mProfiler.profileFd != null&& mProfiler.autoStopProfiler) {stopProfiling = true;}if (a != null) {mNewActivities = null;IActivityManager am = ActivityManagerNative.getDefault();ActivityClientRecord prev;do {if (localLOGV) Slog.v(TAG, "Reporting idle of " + a +" finished=" +(a.activity != null && a.activity.mFinished));if (a.activity != null && !a.activity.mFinished) {try {am.activityIdle(a.token, a.createdConfig, stopProfiling);a.createdConfig = null;} catch (RemoteException ex) {// Ignore}}prev = a;a = a.nextIdle;prev.nextIdle = null;} while (a != null);}if (stopProfiling) {mProfiler.stopProfiling();}ensureJitEnabled();return false;}}

这里我们比较关注的方法就是am.activityIdle(a.token, a.createdConfig, stopProfiling),通知Ams 应用进入到了idle状态。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

        @Overridepublic void handleMessage(Message msg) {switch (msg.what) {case IDLE_TIMEOUT_MSG: {if (DEBUG_IDLE) Slog.d(TAG_IDLE,"handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);if (mService.mDidDexOpt) {mService.mDidDexOpt = false;Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);nmsg.obj = msg.obj;mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);return;}// We don't at this point know if the activity is fullscreen,// so we need to be conservative and assume it isn't.activityIdleInternal((ActivityRecord)msg.obj);} break;case IDLE_NOW_MSG: {if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);activityIdleInternal((ActivityRecord)msg.obj);} break;

IDLE_TIMEOUT_MSG消息,IDLE_NOW_MSG和ActivityManagerService.activityIdle()方法最终都调用到了activityIdleInternal方法。

4017         void activityIdleInternal(ActivityRecord r) {4018             synchronized (mService) {4019                 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
4020             }
4021         }2522     // Checked.
2523     final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2524             Configuration config) {2525         if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
2526
2527         ArrayList<ActivityRecord> stops = null;
2528         ArrayList<ActivityRecord> finishes = null;
2529         ArrayList<UserState> startingUsers = null;
2530         int NS = 0;
2531         int NF = 0;
2532         boolean booting = false;
2533         boolean activityRemoved = false;
2534
2535         ActivityRecord r = ActivityRecord.forTokenLocked(token);
2536         if (r != null) {// 移除IDLE_TIMEOUT_MSG消息
2537             if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
2538                     + Debug.getCallers(4));
2539             mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2540             r.finishLaunchTickingLocked();
2541             if (fromTimeout) {2542                 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
2543             }
2544
2545             // This is a hack to semi-deal with a race condition
2546             // in the client where it can be constructed with a
2547             // newer configuration from when we asked it to launch.
2548             // We'll update with whatever configuration it now says
2549             // it used to launch.
2550             if (config != null) {2551                 r.configuration = config;
2552             }
2553
2554             // We are now idle.  If someone is waiting for a thumbnail from
2555             // us, we can now deliver.
2556             r.idle = true;
2557
2558             //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2559             if (isFrontStack(r.task.stack) || fromTimeout) {2560                 booting = checkFinishBootingLocked();
2561             }
2562         }
2563
2564         if (allResumedActivitiesIdle()) {2565             if (r != null) {// 所有Activity都进入idle状态,调用app进行gc
2566                 mService.scheduleAppGcsLocked();
2567             }
2568
2569             if (mLaunchingActivity.isHeld()) {2570                 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2571                 if (VALIDATE_WAKE_LOCK_CALLER &&
2572                         Binder.getCallingUid() != Process.myUid()) {2573                     throw new IllegalStateException("Calling must be system uid");
2574                 }
2575                 mLaunchingActivity.release();
2576             }
2577             ensureActivitiesVisibleLocked(null, 0);
2578         }
2579
2580         // Atomically retrieve all of the other things to do.// 收集等待执行stop的activity到stops集合,收集要finish的activity到finishes集合
2581         stops = processStoppingActivitiesLocked(true);
2582         NS = stops != null ? stops.size() : 0;
2583         if ((NF = mFinishingActivities.size()) > 0) {2584             finishes = new ArrayList<>(mFinishingActivities);
2585             mFinishingActivities.clear();
2586         }
2587
2588         if (mStartingUsers.size() > 0) {2589             startingUsers = new ArrayList<>(mStartingUsers);
2590             mStartingUsers.clear();
2591         }
2592
2593         // Stop any activities that are scheduled to do so but have been
2594         // waiting for the next one to start.
2595         for (int i = 0; i < NS; i++) {2596             r = stops.get(i);
2597             final ActivityStack stack = r.task.stack;
2598             if (stack != null) {2599                 if (r.finishing) {// 立即执行Activity的finish后续生命周期(为什么有些情况不立即执行finish呢,因为需要切换动画)
2600                     stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2601                 } else {// 执行Activity的stop生命周期。
2602                     stack.stopActivityLocked(r);
2603                 }
2604             }
2605         }
2606
2607         // Finish any activities that are scheduled to do so but have been
2608         // waiting for the next one to start.
2609         for (int i = 0; i < NF; i++) {2610             r = finishes.get(i);
2611             final ActivityStack stack = r.task.stack;
2612             if (stack != null) {// 已经进入finishes的Activity是延迟finish的,已经吊用过finishCurrentActivityLocked,// 这里直接调用destoy方法。
2613                 activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
2614             }
2615         }
2616
2617         if (!booting) {2618             // Complete user switch
2619             if (startingUsers != null) {2620                 for (int i = 0; i < startingUsers.size(); i++) {2621                     mService.finishUserSwitch(startingUsers.get(i));
2622                 }
2623             }
2624             // Complete starting up of background users
2625             if (mStartingBackgroundUsers.size() > 0) {2626                 startingUsers = new ArrayList<UserState>(mStartingBackgroundUsers);
2627                 mStartingBackgroundUsers.clear();
2628                 for (int i = 0; i < startingUsers.size(); i++) {2629                     mService.finishUserBoot(startingUsers.get(i));
2630                 }
2631             }
2632         }
2633
2634         mService.trimApplications();
2635         //dump();
2636         //mWindowManager.dump();
2637
2638         if (activityRemoved) {2639             resumeTopActivitiesLocked();
2640         }
2641
2642         return r;
2643     }

这里主要处理等待stop的Activity和等待finish的Activity。分别调用Activity的生命周期方法来执行Activity的生命周期。不过我这里有个脑洞,手动调用Activity的一些状态上报函数来使Ams进入错乱状态来执行拒绝服务攻击。

应该写了不少错别字,希望csdn什么时候支持语法错误检查。要么准备到别处写去了。

Android Ams对于Activity生命周期的管理相关推荐

  1. Android面试之Activity生命周期详解

    Activity生命周期详解 一 Activity的四种状态: Activity的生命周期中存在四种基本的状态:活动状态(Active/Runing),暂停状态(Paused),停止状态(Stoppe ...

  2. Android 组件系列-----Activity生命周期

    本篇随笔将会深入学习Activity,包括如何定义多个Activity,并设置为默认的Activity.如何从一个Activity跳转到另一个Activity,还有就是详细分析Activity的生命周 ...

  3. Android 插件化原理解析——Activity生命周期管理

    之前的 Android插件化原理解析 系列文章揭开了Hook机制的神秘面纱,现在我们手握倚天屠龙,那么如何通过这种技术完成插件化方案呢?具体来说,插件中的Activity,Service等组件如何在A ...

  4. Android apk动态加载机制的研究(二):资源加载和activity生命周期管理

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了 ...

  5. Activity生命周期管理

    之前的 Android插件化原理解析 系列文章揭开了Hook机制的神秘面纱,现在我们手握倚天屠龙,那么如何通过这种技术完成插件化方案呢?具体来说,插件中的Activity,Service等组件如何在A ...

  6. 【Android 四大组件之Activity】一文吃透Activity 生命周期

    作者:半身风雪 简介:在Android组件中最基本也是最为常见的四大组件: Activity Service服务 Content Provider内容提供者 BroadcastReceiver广播接收 ...

  7. android 生命周期管理,Android Activity生命周期和堆栈管理的详解_Android_脚本之家...

    Activity的生命周期 Activity是Android中的四大组件之一,也是最基本,最重要的组件,是android系统提供一个可视化的,能与用户交换的组件. 系统提供的组件,不需要用户实例化,用 ...

  8. Android doc |Getting Started|部分 转载 --管理Activity生命周期

    原文 https://developer.android.com/training/basics/activity-lifecycle/index.html 原文被部分改动 管理Activity生命周 ...

  9. Android Activity生命周期管理

    http://blog.csdn.net/thl789/article/details/6628463 本文描述Android中Activity的状态,Activity的状态转换,从而总结了Activ ...

最新文章

  1. linux服务器多网卡bond
  2. ads无法启用状态服务器,NAC ADSSO 无法工作在Microsoft 2008服务器版本
  3. 五天带你学完《计算机网络》·第一天·物理层
  4. 为什么我喜欢EJB 3.0并且尤其喜欢EJB 3.1
  5. how is table select_all_icon being loaded
  6. 如何查看某个employee被assign到了哪个sales organization上
  7. LeetCode第45场双周赛-解题报告
  8. 【Flink】Flink keyed State多年的误解 以及 Keyed state redistribute
  9. GCD 深入理解(一)
  10. docker重置mysql密码
  11. 有效提升网站关键词排名的优化技巧
  12. Linux节点释放,关于linux:如何释放Inode的使用量?
  13. php游戏实例,php实现的简易扫雷游戏实例_PHP
  14. 将汉子转化为拼音的js插件
  15. 查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率--及格为>=60,中等为:70-80,优良为:80-90,优秀为:
  16. 跟小博老师一起学习MyBatis ——MyBatis搭建运行环境
  17. javascript 0基础入门
  18. nginx 官方文档翻译
  19. 提升工作效率的神器:电脑版番茄工作软件
  20. POE供电怎么用?常见PoE供电4种工程应用方法

热门文章

  1. 【python实现网络爬虫(5)】第一个Scrapy爬虫实例项目(Scrapy原理及Scrapy爬取名言名句网站信息)
  2. 分享5款开年必备的工具软件
  3. 完全卸载Oracle Database 19c
  4. 跨境电商如何设计出色的落地页:分步指南和5个案例分析
  5. NGS基础名词解释(1)
  6. uni-app下载图片(新手上路)
  7. Angry Birds for Chrome 升级,带来圣诞新关卡和 Mighty Eagle
  8. linux IO方式操作gpio
  9. BUU CTF[CISCN2019 总决赛 Day2 Web1]Easyweb 1
  10. setInterval存在的问题