Step 30.ViewRoot.dispatchFinishedEvent

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

  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. publicvoiddispatchFinishedEvent(intseq,booleanhandled){
  5. Messagemsg=obtainMessage(FINISHED_EVENT);
  6. msg.arg1=seq;
  7. msg.arg2=handled?1:0;
  8. sendMessage(msg);
  9. }
  10. ......
  11. }

和前面的Step 26一样,ViewRoot不是直接处理这个键盘事件,而是把它作为一个消息(FINISHED_EVENT)放在消息队列中去,最后,这个消息由ViewRoot的handleFinishedEvent函数来处理。 Step 31.ViewRoot.handleFinishedEvent

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

  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. voidhandleFinishedEvent(intseq,booleanhandled){
  5. finalKeyEventevent=(KeyEvent)retrievePendingEvent(seq);
  6. ......
  7. if(event!=null){
  8. finalbooleansendDone=seq>=0;
  9. if(!handled){
  10. deliverKeyEventToViewHierarchy(event,sendDone);
  11. return;
  12. }elseif(sendDone){
  13. ......
  14. }else{
  15. ......
  16. }
  17. }
  18. }
  19. ......
  20. }

如果InputMethodManager没有处理这个键盘事件,那么ViewRoot就会调用deliverKeyEventToViewHierarchy函数来把这个键盘事件分发给当前激活的Activity窗口来处理。

Step 32.ViewRoot.deliverKeyEventToViewHierarchy

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

  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. privatevoiddeliverKeyEventToViewHierarchy(KeyEventevent,booleansendDone){
  5. try{
  6. if(mView!=null&&mAdded){
  7. ......
  8. booleankeyHandled=mView.dispatchKeyEvent(event);
  9. }
  10. ......
  11. }finally{
  12. if(sendDone){
  13. finishInputEvent();
  14. }
  15. }
  16. }
  17. ......
  18. }

这个函数首先会调用ViewRoot类的成员变量mView的dispatchKeyEvent来处理这个键盘事件,然后最调用ViewRoot类的finishInputEvent来处理手尾工作。

ViewRoot类的成员变量mView的类型为DecorView,它是由ActivityThread类第一次Resume当前的Activity窗口时创建的,具体可以参考ActivityThread类的handleResumeActivity成员函数,这里就不关注了。

Step 33. DecorView.dispatchKeyEvent

这个函数定义在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java文件中,它是PhoneWindow类的一个内部类:

  1. publicclassPhoneWindowextendsWindowimplementsMenuBuilder.Callback{
  2. ......
  3. privatefinalclassDecorViewextendsFrameLayoutimplementsRootViewSurfaceTaker{
  4. ......
  5. @Override
  6. publicbooleandispatchKeyEvent(KeyEventevent){
  7. ......
  8. finalCallbackcb=getCallback();
  9. finalbooleanhandled=cb!=null&&mFeatureId<0?cb.dispatchKeyEvent(event)
  10. :super.dispatchKeyEvent(event);
  11. ......
  12. }
  13. ......
  14. }
  15. ......
  16. }
这里通过getCallback函数返回的是当前应用程序的激活的Activity窗口的Window.Callback接口,一般它不为NULL,因此,这个函数会调用Activity类的dispatchKeyEvent来处理这个键盘事件。
Step 34. Activity.dispatchKeyEvent

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

  1. publicclassActivityextendsContextThemeWrapper
  2. implementsLayoutInflater.Factory,
  3. Window.Callback,KeyEvent.Callback,
  4. OnCreateContextMenuListener,ComponentCallbacks{
  5. ......
  6. publicbooleandispatchKeyEvent(KeyEventevent){
  7. ......
  8. Viewdecor=mDecor;
  9. if(decor==null)decor=win.getDecorView();
  10. returnevent.dispatch(this,decor!=null
  11. ?decor.getKeyDispatcherState():null,this);
  12. }
  13. ......
  14. }
这里,Activity不是直接处理这个键盘事件,而是通过KeyEvent的dispatch转发一下。注意,KeyEvent的成中函数dispatch的第一个参数的类型是KeyEvent.Callback,而Activity实现了这个接口,因此,这里可以传this引用过去。

Step 35. KeyEvent.dispatch

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

  1. publicclassKeyEventextendsInputEventimplementsParcelable{
  2. ......
  3. publicfinalbooleandispatch(Callbackreceiver,DispatcherStatestate,
  4. Objecttarget){
  5. switch(mAction){
  6. caseACTION_DOWN:{
  7. ......
  8. booleanres=receiver.onKeyDown(mKeyCode,this);
  9. ......
  10. returnres;
  11. }
  12. caseACTION_UP:
  13. ......
  14. returnreceiver.onKeyUp(mKeyCode,this);
  15. caseACTION_MULTIPLE:
  16. finalintcount=mRepeatCount;
  17. finalintcode=mKeyCode;
  18. if(receiver.onKeyMultiple(code,count,this)){
  19. returntrue;
  20. }
  21. ......
  22. returnfalse;
  23. }
  24. returnfalse;
  25. }
  26. ......
  27. }
这里就根据一个键是按下(ACTION_DOWN)、还是松开(ACTION_UP)或者是一个相同的键被多次按下和松开(ACTION_MULTIPLE)等不同事件类型来分别调用Activity的onKeyDown、onKeyUp和onKeyMultiple函数了。
Activity窗口处理完这个键盘事件后,层层返回,最后回到Step 32中,调用finishInputEvent事件来处理一些手尾工,下面我们将会看到这些手尾工是什么。

更多相关文章

  1. C语言函数以及函数的使用
  2. Android探索之旅(第二十一篇)Android中事件冲突的解决收集(持续收录
  3. Android 自定义键盘中禁用点击预览弹窗
  4. android 不自动弹出虚拟键盘
  5. android-EditText输入框被键盘遮挡问题解决方案
  6. Android不让弹出键盘挡住View
  7. Android 仿微信的键盘切换
  8. [Android Studio] Android Studio如何提示函数用法
  9. Android交互体验必知:功能按键事件

随机推荐

  1. View事件分发机制
  2. Android(安卓)官方架构组件(三)——ViewMod
  3. Android API 中文 (53) ―― BaseAdapter
  4. android wifi debug 调试
  5. 【流媒體】 Android 实时视频编码—H.264
  6. Android(安卓)EditText常用技能,包括clear
  7. Coroutines in Android - One Shot and M
  8. -用Gradle 构建你的android程序
  9. Android(安卓)使用Stetho在Chrome浏览器
  10. 把TextView中的文字添加阴影效果及Style