上接:Android应用程序键盘(Keyboard)消息处理机制分析(三)
----
4. 应用程序注销键盘消息接收通道的过程分析
当Activity窗口创建时,它会向InputManager注册键盘消息接收通道,而当Activity窗口销毁时,它就会向InputManager注销前面注册的键盘消息接收通道了,本节内容就来看看应用程序注销键盘消息接收通道的过程。
当我们按下键盘上的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; // is this activity's window visible?
- boolean idle; // has the activity gone idle?
- ......
- public void windowsVisible() {
- synchronized(service) {
- ......
- if (!nowVisible) {
- nowVisible = true;
- if (!idle) {
- .......
- } else {
- // If this activity was already idle, then we now need to
- // make sure we perform the full stop of any activities
- // that are waiting to do so. This is because we won't
- // do that while they are still waiting for this one to
- // become visible.
- final int N = stack.mWaitingVisibleActivities.size();
- if (N > 0) {
- for (int i=0; i<N; 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);
- }
- }
- ......
- }
- }
- }
- ......
- }
- final int N = stack.mWaitingVisibleActivities.size();
- if (N > 0) {
- for (int i=0; i<N; 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);
- }
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<ActivityRecord> stops = null;
- ......
- int NS = 0;
- ......
- synchronized (mService) {
- ......
- // Atomically retrieve all of the other things to do.
- stops = processStoppingActivitiesLocked(true);
- NS = stops != null ? stops.size() : 0;
- ......
- }
- int i;
- ......
- // Stop any activities that are scheduled to do so but have been
- // waiting for the next one to start.
- for (i=0; i<NS; i++) {
- ActivityRecord r = (ActivityRecord)stops.get(i);
- synchronized (mService) {
- if (r.finishing) {
- finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
- } else {
- ......
- }
- }
- }
- ......
- }
- ......
- }
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) {
- ......
- // make sure the record is cleaned out of other places.
- 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) {
- // If this activity is already stopped, we can just finish
- // it right now.
- return destroyActivityLocked(r, true) ? null : r;
- } else {
- ......
- }
- return r;
- }
- ......
- }
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;
- }
- ......
- }
- r.app.thread.scheduleDestroyActivity(r, r.finishing,
- r.configChangeFlags);
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);
- }
- ......
- }
- ......
- }
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);
- }
- ......
- }
- ......
- }
- ......
- }
- ......
- }
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;
- }
- ......
- }
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);
- ......
- }
- }
- ......
- }
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 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();
- }
- }
- }
- ......
- }
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) {
- }
- ......
- }
- ......
- }
我们先来看注销注册在应用程序这一侧的Client端InputChannel,然后再回过头来分析注销注册在InputManager这一侧的Server端InputChannel。
Step 12. InputQueue.unregisterInputChannel
这个函数定义在frameworks/base/core/java/android/view/InputQueue.java文件中:
- public final class InputQueue {
- ......
- public static void unregisterInputChannel(InputChannel inputChannel) {
- ......
- synchronized (sLock) {
- ......
- nativeUnregisterInputChannel(inputChannel);
- }
- }
- ......
- }
Step 13. InputQueue.nativeUnregisterInputChannel
这个函数定义在frameworks/base/core/jni/android_view_InputQueue.cpp文件中:
- static void android_view_InputQueue_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
- jobject inputChannelObj) {
- status_t status = gNativeInputQueue.unregisterInputChannel(env, inputChannelObj);
- ......
- }
Step 14. NativeInputQueue.unregisterInputChannel
这个函数定义在frameworks/base/core/jni/android_view_InputQueue.cpp文件中:
- status_t NativeInputQueue::unregisterInputChannel(JNIEnv* env, jobject inputChannelObj) {
- sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
- inputChannelObj);
- ......
- { // acquire lock
- AutoMutex _l(mLock);
- ssize_t connectionIndex = getConnectionIndex(inputChannel);
- ......
- sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
- mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
- connection->status = Connection::STATUS_ZOMBIE;
- connection->looper->removeFd(inputChannel->getReceivePipeFd());
- env->DeleteGlobalRef(connection->inputHandlerObjGlobal);
- connection->inputHandlerObjGlobal = NULL;
- ......
- } // release lock
- ......
- return OK;
- }
- ssize_t connectionIndex = getConnectionIndex(inputChannel);
- ......
- sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
- mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
- connection->looper->removeFd(inputChannel->getReceivePipeFd());
最后将Connection对象中的回调对象inputHandlerOjbGlobal对象删除:
- env->DeleteGlobalRef(connection->inputHandlerObjGlobal);
- connection->inputHandlerObjGlobal = NULL;
注册在应用程序这一侧的Client端InputChannel被注销以后,回到前面的Step 11中,我们继续分析注销注册在InputManager这一侧的Server端InputChannel。
Step 15. WindowManagerService.Session.remove
这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java文件中:
- public class WindowManagerService extends IWindowManager.Stub
- implements Watchdog.Monitor {
- ......
- private final class Session extends IWindowSession.Stub
- implements IBinder.DeathRecipient {
- ......
- public void remove(IWindow window) {
- removeWindow(this, window);
- }
- ......
- }
- ......
- }
这个函数只是简单地调用其外部类WindowManagerService的removeWindow函数来进一步执行操作。
Step 16. WindowManagerService.removeWindow
这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java文件中:
- public class WindowManagerService extends IWindowManager.Stub
- implements Watchdog.Monitor {
- ......
- public void removeWindow(Session session, IWindow client) {
- synchronized(mWindowMap) {
- WindowState win = windowForClientLocked(session, client, false);
- if (win == null) {
- return;
- }
- removeWindowLocked(session, win);
- }
- }
- ......
- }
回忆一下前面我们在分析应用程序注册键盘消息管道的过程时,在Step 11(WindowManagerService.addWindow)中,WindowManagerService为这个即将要激活的Activity窗口创建了一个WindowState对象win,创建的时候,使用了从ViewRoot中传过来的两个参数,分别是一个Session对象session和一个IWindow对象client。
在这个函数中,ViewRoot传过来的两个参数session和client和上面说的两个参数是一致的,因此,这个函数首先通过参数session和client得到一个WindowState对象win,然后调用removeWindowLocked来把它从WindowManagerService删除。
Step 17. WindowManagerService.removeWindowLocked
这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java文件中:
- public class WindowManagerService extends IWindowManager.Stub
- implements Watchdog.Monitor {
- ......
- public void removeWindowLocked(Session session, WindowState win) {
- ......
- win.disposeInputChannel();
- ......
- }
- ......
- }
Step 18. WindowState.disposeInputChannel
这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java文件中:
- public class WindowManagerService extends IWindowManager.Stub
- implements Watchdog.Monitor {
- ......
- private final class WindowState implements WindowManagerPolicy.WindowState {
- ......
- void disposeInputChannel() {
- if (mInputChannel != null) {
- mInputManager.unregisterInputChannel(mInputChannel);
- mInputChannel.dispose();
- mInputChannel = null;
- }
- }
- ......
- }
- ......
- }
Step 19. InputManager.unregisterInputChannel
这个函数定义在frameworks/base/services/java/com/android/server/InputManager.java文件中:
- public class InputManager {
- ......
- public void unregisterInputChannel(InputChannel inputChannel) {
- ......
- nativeUnregisterInputChannel(inputChannel);
- }
- ......
- }
Step 20. InputManager.nativeUnregisterInputChannel
这个函数定义在frameworks/base/services/jni/com_android_server_InputManager.cpp文件中:
- static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
- jobject inputChannelObj) {
- ......
- sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
- inputChannelObj);
- ......
- status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
- ......
- }
Step 21. NativeInputManager.unregisterInputChannel
这个函数定义在frameworks/base/services/jni/com_android_server_InputManager.cpp文件中:
- status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
- const sp<InputChannel>& inputChannel) {
- ......
- return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
- }
Step 22. InputDispatcher.unregisterInputChannel
这个函数定义在frameworks/base/libs/ui/InputDispatcher.cpp文件中:
- status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
- ......
- { // acquire lock
- AutoMutex _l(mLock);
- ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
- ......
- sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
- mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
- ......
- mLooper->removeFd(inputChannel->getReceivePipeFd());
- .....
- } // release lock
- ......
- return OK;
- }
- ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
- ......
- sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
- mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
这样, 应用程序注销键盘消息接收通道的过程就分析完成了,整个应用程序键盘消息处理机制也分析完成了,这是一个比较复杂的过程,要完全理解它还需要花费一些努力和时间,不过,理解了这个过程之后,对Android应用程序框架层的理解就更进一步了。