Android应用程序键盘(Keyboard)消息处理机制分析(20)
Step 24. InputQueue.dispatchKeyEvent
这个函数定义在frameworks/base/core/java/android/view/InputQueue.java文件中:
- publicfinalclassInputQueue{
- ......
- privatestaticvoiddispatchKeyEvent(InputHandlerinputHandler,
- KeyEventevent,longfinishedToken){
- RunnablefinishedCallback=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文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- privatefinalInputHandlermInputHandler=newInputHandler(){
- publicvoidhandleKey(KeyEventevent,RunnablefinishedCallback){
- startInputEvent(finishedCallback);
- dispatchKey(event,true);
- }
- ......
- };
- ......
- }
这个函数首先调用其外部类ViewRoot的startInputEvent成员函数来把回调对象finishedCallback保存下来:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- privatevoidstartInputEvent(RunnablefinishedCallback){
- ......
- mFinishedCallback=finishedCallback;
- }
- ......
- }
然后再调用其外部类ViewRoot的dispatchKey成员函数来进一步处这个键盘事件。
Step 26.ViewRoot.dispatchKey
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- privatevoiddispatchKey(KeyEventevent,booleansendDone){
- ......
- Messagemsg=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文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- privatevoiddeliverKeyEvent(KeyEventevent,booleansendDone){
- //IfmViewisnull,wejustconsumethekeyeventbecauseitdoesn't
- //makesensetodoanythingelsewithit.
- booleanhandled=mView!=null
- ?mView.dispatchKeyEventPreIme(event):true;
- ......
- //Ifitispossibleforthiswindowtointeractwiththeinput
- //methodwindow,thenwewanttofirstdispatchourkeyevents
- //totheinputmethod.
- if(mLastWasImTarget){
- InputMethodManagerimm=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文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- staticclassInputMethodCallbackextendsIInputMethodCallback.Stub{
- privateWeakReference<ViewRoot>mViewRoot;
- publicInputMethodCallback(ViewRootviewRoot){
- mViewRoot=newWeakReference<ViewRoot>(viewRoot);
- }
- publicvoidfinishedEvent(intseq,booleanhandled){
- finalViewRootviewRoot=mViewRoot.get();
- if(viewRoot!=null){
- viewRoot.dispatchFinishedEvent(seq,handled);
- }
- }
- ......
- }
- ......
- }
这个函数最终调用ViewRoot的dispatchFinishedEvent来进一步处理。
更多相关文章
- 【Android】事件分发机制源码解析
- Android的NDK开发(3)————JNI数据类型的详解
- Android(安卓)Activity之间跳转出现短暂黑屏的处理方法(转)
- Android(安卓)GPS基础
- Android图片圆角
- Android的NDK开发(3)————JNI数据类型的详解
- Android电源管理
- Android中Touch事件的处理
- Android日志系统Logcat源代码简要分析