当我们按下键盘上的Back键时,当前激活的Activity窗口就会被失去焦点,但是这时候它还没有被销毁,它的状态被设置为Stopped;当新的Activity窗口即将要显示时,它会通知WindowManagerService,这时候WindowManagerService就会处理当前处理Stopped状态的Activity窗口了,要执行的操作就是销毁它们了,在销毁的时候,就会注销它们之前所注册的键盘消息接收通道。
新的Activity窗口通知WindowManagerService它即将要显示的过程比较复杂,但是它与我们本节要介绍的内容不是很相关,因此,这里就略过大部过程了,我们从ActvitiyRecord的windowsVisible函数开始分析。注意,这里的ActivityRecord是新的Activity窗口在ActivityManangerService的代表,而那些处于Stopped状态的Activity窗口
会放在ActivityStack类的一个等待可见的mWaitingVisibleActivities列表里面,事实于,对于那些Stopped状态的Activity窗口来说,它们是等待销毁,而不是等待可见。
像前面一样,我们先来看一张应用程序注销键盘消息接收通道的过程的序列图,然后根据这个序列图来详细分析互一个步骤:
点击查看大图
Step 1. ActivityRecord.windowsVisible
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityRecord.java文件中:
- class ActivityRecord extends IApplicationToken.Stub {
- ......
- boolean nowVisible;
- boolean idle;
- ......
-
-
- public void windowsVisible() {
- synchronized(service) {
- ......
-
- if (!nowVisible) {
- nowVisible = true;
- if (!idle) {
- .......
- } else {
-
-
-
-
-
- final int N = stack.mWaitingVisibleActivities.size();
- if (N > 0) {
- for (int i=0; i
- ActivityRecord r = (ActivityRecord)
- stack.mWaitingVisibleActivities.get(i);
- r.waitingVisible = false;
- ......
- }
- stack.mWaitingVisibleActivities.clear();
-
- Message msg = Message.obtain();
- msg.what = ActivityStack.IDLE_NOW_MSG;
- stack.mHandler.sendMessage(msg);
-
- }
- }
- ......
- }
- }
- }
-
- ......
- }
应用程序中的每一个Activity在ActivityManagerService都有一个代表ActivityRecord,它们以堆栈的形式组织在ActivityManaerService中的ActivityStack中。一个即将要显示,但是还没有显示的Activity,它在ActivityManagerService中的ActivityRecord的成员变量nowVisible为false,而成员变量idle为ture,表示这个即将要显示的Activity窗口处于空闲状态。因此,在上面的这个函数中,会执行下面的语句:
- final int N = stack.mWaitingVisibleActivities.size();
- if (N > 0) {
- for (int i=0; i
- ActivityRecord r = (ActivityRecord)
- stack.mWaitingVisibleActivities.get(i);
- r.waitingVisible = false;
- ......
- }
- stack.mWaitingVisibleActivities.clear();
-
- Message msg = Message.obtain();
- msg.what = ActivityStack.IDLE_NOW_MSG;
- stack.mHandler.sendMessage(msg);
-
- }
前面我们说过,当用户按下键盘上的Back键时,当前激活的Activity记录就被放在ActivityStack对象stack的成员变量mWaitingVisibleActivities中了,这时候就要对它进行处理了。首先是将它们的Activity记录的waitingVisible设置为false,然后就把它们从ActivityStack对象stack的成员变量mWaitingVisibleActivities清空,最后向ActivityStack对象stack发送一个ActivityStack.IDLE_NOW_MSG消息。这个消息最终是由ActivityStack类的activityIdleInternal函数来处理的。
Step 2. ActivityStack.activityIdleInternal
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
- public class ActivityStack {
- ......
-
- final void activityIdleInternal(IBinder token, boolean fromTimeout,
- Configuration config) {
- ......
-
- ArrayList stops = null;
- ......
-
- int NS = 0;
- ......
-
- synchronized (mService) {
- ......
-
-
- stops = processStoppingActivitiesLocked(true);
- NS = stops != null ? stops.size() : 0;
- ......
- }
-
- int i;
-
- ......
-
-
-
- for (i=0; i
- ActivityRecord r = (ActivityRecord)stops.get(i);
- synchronized (mService) {
- if (r.finishing) {
- finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
- } else {
- ......
- }
- }
- }
-
- ......
- }
-
- ......
- }
这个函数首先会调用processStoppingActivitiesLocked函数把所有处于Stopped状态的Activity取回来,然后逐个分析它们,如果它们的ActivityRecord中的finishing成员变量为true,就说明这个Activity需要销毁了,于是,就调用finishCurrentActivityLocked函数来销毁它们。
Step 3. ActivityStack.finishCurrentActivityLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
- public class ActivityStack {
- ......
-
- private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
- int mode) {
- ......
-
- return finishCurrentActivityLocked(r, index, mode);
- }
-
- private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
- int index, int mode) {
- ......
-
-
- mStoppingActivities.remove(r);
- mWaitingVisibleActivities.remove(r);
- ......
-
- final ActivityState prevState = r.state;
- r.state = ActivityState.FINISHING;
-
- if (mode == FINISH_IMMEDIATELY
- || prevState == ActivityState.STOPPED
- || prevState == ActivityState.INITIALIZING) {
-
-
- return destroyActivityLocked(r, true) ? null : r;
- } else {
- ......
- }
-
- return r;
- }
-
- ......
- }
从上面的Step 2中传进来的参数mode为FINISH_IMMEDIATELY,并且这个即将要被销毁的Activity的状态为Stopped,因此,接下来就会调用destroyActivityLocked函数来销毁它。
Step 4. ActivityStack.destroyActivityLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
- public class ActivityStack {
- ......
-
- final boolean destroyActivityLocked(ActivityRecord r,
- boolean removeFromApp) {
- ......
-
- boolean removedFromHistory = false;
-
- ......
-
- final boolean hadApp = r.app != null;
-
- if (hadApp) {
- ......
-
- try {
- ......
- r.app.thread.scheduleDestroyActivity(r, r.finishing,
- r.configChangeFlags);
- } catch (Exception e) {
- ......
- }
-
- ......
- } else {
- ......
- }
-
- ......
-
- return removedFromHistory;
- }
-
- ......
- }
在前面一篇文章 Android应用程序启动过程源代码分析
中,我们说到,每一个应用程序进程在ActivityManagerService中,都ProcessRecord记录与之对应,而每一个Activity,都是运行在一个进程上下文中,因此,在ActivityManagerService中,每一个ActivityRecord的app成员变量都应该指向一个ProcessRecord记录,于是,这里得到的hadApp为true。在ProcessRecord类中,有一个成员变量thread,它的类型为IApplicationThread。在文章 Android应用程序启动过程源代码分析
中,我们也曾经说过,每一个应用程序在启动的时候,它都会在内部创建一个ActivityThread对象,而在这个ActivityThread对象中,有一个成员变量mAppThread,它的类型为ApplicationThread,这是一个Binder对象,专门用来负责在应用程序和ActivityManagerService之间执行进程间通信工作的。应用程序在启动的时候,就会将这个Binder对象传递给ActivityManagerService,而ActivityManagerService就会把它保存在相应的ProcessRecord记录的thread成员变量中。因此,ProcessRecord记录的thread成员变量其实就是ApplicationThread对象的远程接口,于是,执行下面这个语句的时候:
- r.app.thread.scheduleDestroyActivity(r, r.finishing,
- r.configChangeFlags);
就会进入到ApplicationThread类中的scheduleDestroyActivity函数来。
Step 5. ApplicationThread.scheduleDestroyActivity
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- public final class ActivityThread {
- ......
-
- private final class ApplicationThread extends ApplicationThreadNative {
- ......
-
- public final void scheduleDestroyActivity(IBinder token, boolean finishing,
- int configChanges) {
-
- queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
- configChanges);
- }
-
- ......
- }
-
- ......
- }
这个函数调用外部类ActivityThread的queueOrSendMessage函数来往应用程序的消息队列中发送一个H.DESTROY_ACTIVITY消息,这个消息最终由ActivityThread类的handleDestroyActivity函数来处理。
Step 6. ActivityThread.handleDestroyActivity
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- public final class ActivityThread {
- ......
-
- private final void handleDestroyActivity(IBinder token, boolean finishing,
- int configChanges, boolean getNonConfigInstance) {
- ......
-
- ActivityClientRecord r = performDestroyActivity(token, finishing,
- configChanges, getNonConfigInstance);
- if (r != null) {
- WindowManager wm = r.activity.getWindowManager();
- View v = r.activity.mDecor;
- if (v != null) {
- ......
-
- if (r.activity.mWindowAdded) {
- wm.removeViewImmediate(v);
- }
-
- ......
- }
- ......
- }
-
- ......
- }
-
- ......
- }
这里首先调用performDestroyActivity来执行一些销毁Activity的操作,期间就会调用Activity的onDestroy函数让Activity本身有机会执行一些销毁前的工作了。这里通过r.activity.getWindowManager函数返回的是一个LocalWindowManager对象,而通过r.activity.mDecor得到的是一个DecorView对象,这些都是在Activity启动的时候设置好的。函数最后调用LocalWindowManager对象wm的removeViewImmediate函员来从LocalWindowManager移除这个DecorView对象。
Step 7. LocalWindowManager.removeViewImmediate
这个函数定义在frameworks/base/core/java/android/view/Window.java文件中:
- public abstract class Window {
- ......
-
- private class LocalWindowManager implements WindowManager {
- ......
-
- public final void removeViewImmediate(View view) {
- mWindowManager.removeViewImmediate(view);
- }
-
- ......
-
- private final WindowManager mWindowManager;
- }
-
- ......
- }
LocalWindowManager类的成员变量mWindowManager是一个WndowManagerImpl对象,这个函数只是简单地调用WndowManagerImpl类的removeViewImmediate来进一步处理。
Step 8. WndowManagerImpl.removeViewImmediate
这个函数定义在frameworks/base/core/java/android/view/WindowManagerImpl.java文件中:
- public class WindowManagerImpl implements WindowManager {
- ......
-
- public void removeViewImmediate(View view) {
- synchronized (this) {
- int index = findViewLocked(view, true);
- ViewRoot root = mRoots[index];
- ......
-
- root.die(true);
-
- ......
- }
- }
-
- ......
- }
这个函数首先是找到这个view所属的ViewRoot对象root,然后调用这个root对象的die函数来销毁它。
Step 9. ViewRoot.die
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- public void die(boolean immediate) {
- if (immediate) {
- doDie();
- } else {
- ......
- }
- }
-
- ......
- }
上面Step 8传进来的immediate参数为true,因此,这里直接调用doDie函数来进一步处理。
Step 10. ViewRoot.doDie
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- void doDie() {
- ......
-
- synchronized (this) {
- ......
-
- if (mAdded) {
- mAdded = false;
- dispatchDetachedFromWindow();
- }
- }
- }
-
- ......
- }
当我们把Activity窗口中的View添加到一个ViewRoot对象时,就会把它的成员变量mAdded设置为true,这样就表示这个ViewRoot中有View存在,于是,这里就会调用dispatchDetachedFromWindow函数来进一步处理。
Step 11. ViewRoot.ispatchDetachedFromWindow
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- void dispatchDetachedFromWindow() {
- ......
-
- if (mInputChannel != null) {
- if (mInputQueueCallback != null) {
- ......
- } else {
- InputQueue.unregisterInputChannel(mInputChannel);
- }
- }
-
- try {
- sWindowSession.remove(mWindow);
- } catch (RemoteException e) {
- }
-
- ......
- }
-
- ......
- }