Step 24. InputQueue.dispatchKeyEvent

这个函数定义在frameworks/base/core/java/android/view/InputQueue.java文件中:

  1. publicfinalclassInputQueue{
  2. ......
  3. privatestaticvoiddispatchKeyEvent(InputHandlerinputHandler,
  4. KeyEventevent,longfinishedToken){
  5. RunnablefinishedCallback=FinishedCallback.obtain(finishedToken);
  6. inputHandler.handleKey(event,finishedCallback);
  7. }
  8. ......
  9. }

这个函数首先会创建一个FinishedCallback类型的对象finishedCallback,FinishedCallback是InputQueue的一个内部类,它继承于Runnable类。这个finishedCallback对象是提供给当前Activity窗口的,当它处理完毕键盘事件后,需要通过消息分发的方式来回调这个finishedCallback对象,以及InputQueue类处理一个手尾的工作,后面我们会分析到。

这里的inputHandler对象是在前面分析应用程序注册键盘消息接收通道的过程时,在Step 1(ViewRoot.setView)中传进来的:

  1. InputQueue.registerInputChannel(mInputChannel,mInputHandler,
  2. Looper.myQueue());

它是ViewRoot类的一个成员变量mInputHandler。因此,这里将调用ViewRoot类的内部对象mInputHandler的成员函数handleKey来处理键盘事件。

Step 25. InputHandler.handleKey

这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:

  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. privatefinalInputHandlermInputHandler=newInputHandler(){
  5. publicvoidhandleKey(KeyEventevent,RunnablefinishedCallback){
  6. startInputEvent(finishedCallback);
  7. dispatchKey(event,true);
  8. }
  9. ......
  10. };
  11. ......
  12. }

这个函数首先调用其外部类ViewRoot的startInputEvent成员函数来把回调对象finishedCallback保存下来:

  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. privatevoidstartInputEvent(RunnablefinishedCallback){
  5. ......
  6. mFinishedCallback=finishedCallback;
  7. }
  8. ......
  9. }

然后再调用其外部类ViewRoot的dispatchKey成员函数来进一步处这个键盘事件。

Step 26.ViewRoot.dispatchKey

这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:

  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. privatevoiddispatchKey(KeyEventevent,booleansendDone){
  5. ......
  6. Messagemsg=obtainMessage(DISPATCH_KEY);
  7. msg.obj=event;
  8. msg.arg1=sendDone?1:0;
  9. ......
  10. sendMessageAtTime(msg,event.getEventTime());
  11. }
  12. ......
  13. }

ViewRoot不是直接处理这个键盘事件,而是把作为一个消息(DISPATCH_KEY)它放到消息队列中去处理,这个消息最后由ViewRoot类的deliverKeyEvent成员函数来处理。
Step 27.ViewRoot.deliverKeyEvent

这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:

  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. privatevoiddeliverKeyEvent(KeyEventevent,booleansendDone){
  5. //IfmViewisnull,wejustconsumethekeyeventbecauseitdoesn't
  6. //makesensetodoanythingelsewithit.
  7. booleanhandled=mView!=null
  8. ?mView.dispatchKeyEventPreIme(event):true;
  9. ......
  10. //Ifitispossibleforthiswindowtointeractwiththeinput
  11. //methodwindow,thenwewanttofirstdispatchourkeyevents
  12. //totheinputmethod.
  13. if(mLastWasImTarget){
  14. InputMethodManagerimm=InputMethodManager.peekInstance();
  15. if(imm!=null&&mView!=null){
  16. ......
  17. imm.dispatchKeyEvent(mView.getContext(),seq,event,
  18. mInputMethodCallback);
  19. return;
  20. }
  21. }
  22. ......
  23. }
  24. ......
  25. }

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文件中:

  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. staticclassInputMethodCallbackextendsIInputMethodCallback.Stub{
  5. privateWeakReference<ViewRoot>mViewRoot;
  6. publicInputMethodCallback(ViewRootviewRoot){
  7. mViewRoot=newWeakReference<ViewRoot>(viewRoot);
  8. }
  9. publicvoidfinishedEvent(intseq,booleanhandled){
  10. finalViewRootviewRoot=mViewRoot.get();
  11. if(viewRoot!=null){
  12. viewRoot.dispatchFinishedEvent(seq,handled);
  13. }
  14. }
  15. ......
  16. }
  17. ......
  18. }

这个函数最终调用ViewRoot的dispatchFinishedEvent来进一步处理。

更多相关文章

  1. 【Android】事件分发机制源码解析
  2. Android的NDK开发(3)————JNI数据类型的详解
  3. Android(安卓)Activity之间跳转出现短暂黑屏的处理方法(转)
  4. Android(安卓)GPS基础
  5. Android图片圆角
  6. Android的NDK开发(3)————JNI数据类型的详解
  7. Android电源管理
  8. Android中Touch事件的处理
  9. Android日志系统Logcat源代码简要分析

随机推荐

  1. C#连接Oracle的实例教程
  2. 实现一个验证码生成类(含数字,拼音,汉字)
  3. SignalR Self Host多端消息推送服务实例(
  4. ASP.NET Core简单介绍教程(1)_实用技巧
  5. 带你掌握OOM框架AutoMapper使用实例
  6. SignalR Self Host多端消息推送服务介绍(
  7. ASP.NET Core环境设置教程(2)_实用技巧
  8. 详解关于Blog实现一个日历的实例教程
  9. ASP.NET中的参数与特殊类型的实例详解
  10. ASP.NET Core新建项目教程(3)_实用技巧