分析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 there
804 * 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 (the
808 * screen turning off).
809 * @param resuming True if this is being called as part of resuming the top activity, so
810 * 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. If
812 * 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 for
814 * 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的Activity
845 mPausingActivity = prev;
846 mLastPausedActivity = prev;
847 mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
848 || (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 is
883 // 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 new
890 // activity has started. If we're pausing the activity just because
891 // the screen is being turned off and the UI is sleeping, don't interrupt
892 // 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 complete
901 // 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 the
908 // 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 the
919 // 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
@Override
public 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: " + r
937 + (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 != null
943 ? 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}.
*
* 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 {
@Override
public 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
@Override
public 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什么时候支持语法错误检查。要么准备到别处写去了。