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. Android(安卓)Universal Image Loader 源码分析
  2. android framework
  3. Android应用程序组件Content Provider的启动过程源代码分析(6)
  4. Android系统进程Zygote启动过程的源代码分析(3)
  5. IntentService简介
  6. [Android(安卓)Studio] Android(安卓)Studio如何提示函数用法
  7. Android交互体验必知:功能按键事件
  8. 解读Android(安卓)LOG机制的实现:c/c++域使用LOG
  9. android 触摸(Touch)事件、点击(Click)事件的区别(详细解析)

随机推荐

  1. Android系统的架构
  2. Android样式和主题
  3. Looper
  4. Android绘图机制与处理技巧——Android图
  5. Android之自制的分页表格控件
  6. Android最新源码4.3下载-教程 2013-11
  7. Android应用程序与SurfaceFlinger服务的
  8. Unity 与Android的交互(Android(安卓)stu
  9. Android小項目之---ListView实现论坛管理
  10. 博客开篇