本文共 4114 字,大约阅读时间需要 13 分钟。
Step 24. InputQueue.dispatchKeyEvent
这个函数定义在frameworks/base/core/java/android/view/InputQueue.java文件中:
- public final class InputQueue {
- ......
-
- private static void dispatchKeyEvent(InputHandler inputHandler,
- KeyEvent event, long finishedToken) {
- Runnable finishedCallback = FinishedCallback.obtain(finishedToken);
- inputHandler.handleKey(event, finishedCallback);
- }
-
- ......
- }
这个函数首先会创建一个FinishedCallback类型的对象finishedCallback,FinishedCallback是InputQueue的一个内部类,它继承于Runnable类。这个finishedCallback对象是提供给当前Activity窗口的,当它处理完毕键盘事件后,需要通过消息分发的方式来回调这个finishedCallback对象,以及InputQueue类处理一个手尾的工作,后面我们会分析到。
这里的inputHandler对象是在前面分析应用程序注册键盘消息接收通道的过程时,在Step 1(ViewRoot.setView)中传进来的:
- InputQueue.registerInputChannel(mInputChannel, mInputHandler,
- Looper.myQueue());
它是ViewRoot类的一个成员变量mInputHandler。因此,这里将调用ViewRoot类的内部对象mInputHandler的成员函数handleKey来处理键盘事件。
Step 25. InputHandler.handleKey
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- private final InputHandler mInputHandler = new InputHandler() {
- public void handleKey(KeyEvent event, Runnable finishedCallback) {
- startInputEvent(finishedCallback);
- dispatchKey(event, true);
- }
- ......
- };
-
- ......
- }
这个函数首先调用其外部类ViewRoot的startInputEvent成员函数来把回调对象finishedCallback保存下来:
- public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- private void startInputEvent(Runnable finishedCallback) {
- ......
-
- mFinishedCallback = finishedCallback;
- }
-
- ......
- }
然后再调用其外部类ViewRoot的dispatchKey成员函数来进一步处这个键盘事件。
Step 26. ViewRoot.dispatchKey
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- private void dispatchKey(KeyEvent event, boolean sendDone) {
- ......
-
- Message msg = obtainMessage(DISPATCH_KEY);
- msg.obj = event;
- msg.arg1 = sendDone ? 1 : 0;
-
- ......
-
- sendMessageAtTime(msg, event.getEventTime());
- }
-
- ......
- }
ViewRoot不是直接处理这个键盘事件,而是把作为一个消息(DISPATCH_KEY)它放到消息队列中去处理,这个消息最后由ViewRoot类的deliverKeyEvent成员函数来处理。
Step 27. ViewRoot.deliverKeyEvent
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- private void deliverKeyEvent(KeyEvent event, boolean sendDone) {
-
-
- boolean handled = mView != null
- ? mView.dispatchKeyEventPreIme(event) : true;
- ......
-
-
-
-
- if (mLastWasImTarget) {
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null && mView != null) {
- ......
-
- imm.dispatchKeyEvent(mView.getContext(), seq, event,
- mInputMethodCallback);
- return;
- }
- }
- ......
- }
-
- ......
- }
ViewRoot在把这个键盘事件分发给当前激活的Activity窗口处理之前,首先会调用InputMethodManager的dispatchKeyEvent成员函数来处理这个键盘事件。InputMethodManager处理完这个键盘事件后,再回调用这里的mInputMethodCallback对象的finishedEvent成员函数来把键盘事件分发给当前激活的Activity窗口处理。当然,在把这个键盘事件分发给InputMethodManager处理之前,ViewRoot也会先把这个键盘事件分发给当前激活的Activity窗口的dispatchKeyEventPreIme成员函数处理。
Step 28. InputMethodManager.dispatchKeyEvent
这个函数定义在frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java文件中。这是一个输入法相关的类,我们这里就不关注了,只要知道当输入法处理完成之后,它就会调用ViewRoot类的mInputMehtodCallback对象的finishedEvent成员函数。
Step 29. InputMethodCallack.finishedEvent
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- static class InputMethodCallback extends IInputMethodCallback.Stub {
- private WeakReference<ViewRoot> mViewRoot;
-
- public InputMethodCallback(ViewRoot viewRoot) {
- mViewRoot = new WeakReference<ViewRoot>(viewRoot);
- }
-
- public void finishedEvent(int seq, boolean handled) {
- final ViewRoot viewRoot = mViewRoot.get();
- if (viewRoot != null) {
- viewRoot.dispatchFinishedEvent(seq, handled);
- }
- }
-
- ......
- }
-
- ......
- }
这个函数最终调用ViewRoot的dispatchFinishedEvent来进一步处理。
转载地址:http://flusa.baihongyu.com/