Android应用程序键盘(Keyboard)消息处理机制分析(21)
Step 30.ViewRoot.dispatchFinishedEvent
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- publicvoiddispatchFinishedEvent(intseq,booleanhandled){
- Messagemsg=obtainMessage(FINISHED_EVENT);
- msg.arg1=seq;
- msg.arg2=handled?1:0;
- sendMessage(msg);
- }
- ......
- }
和前面的Step 26一样,ViewRoot不是直接处理这个键盘事件,而是把它作为一个消息(FINISHED_EVENT)放在消息队列中去,最后,这个消息由ViewRoot的handleFinishedEvent函数来处理。 Step 31.ViewRoot.handleFinishedEvent
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- voidhandleFinishedEvent(intseq,booleanhandled){
- finalKeyEventevent=(KeyEvent)retrievePendingEvent(seq);
- ......
- if(event!=null){
- finalbooleansendDone=seq>=0;
- if(!handled){
- deliverKeyEventToViewHierarchy(event,sendDone);
- return;
- }elseif(sendDone){
- ......
- }else{
- ......
- }
- }
- }
- ......
- }
如果InputMethodManager没有处理这个键盘事件,那么ViewRoot就会调用deliverKeyEventToViewHierarchy函数来把这个键盘事件分发给当前激活的Activity窗口来处理。
Step 32.ViewRoot.deliverKeyEventToViewHierarchy
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- privatevoiddeliverKeyEventToViewHierarchy(KeyEventevent,booleansendDone){
- try{
- if(mView!=null&&mAdded){
- ......
- booleankeyHandled=mView.dispatchKeyEvent(event);
- }
- ......
- }finally{
- if(sendDone){
- finishInputEvent();
- }
- }
- }
- ......
- }
这个函数首先会调用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类的一个内部类:
- publicclassPhoneWindowextendsWindowimplementsMenuBuilder.Callback{
- ......
- privatefinalclassDecorViewextendsFrameLayoutimplementsRootViewSurfaceTaker{
- ......
- @Override
- publicbooleandispatchKeyEvent(KeyEventevent){
- ......
- finalCallbackcb=getCallback();
- finalbooleanhandled=cb!=null&&mFeatureId<0?cb.dispatchKeyEvent(event)
- :super.dispatchKeyEvent(event);
- ......
- }
- ......
- }
- ......
- }
Step 34. Activity.dispatchKeyEvent
这个函数定义在frameworks/base/core/java/android/app/Activity.java文件中:
- publicclassActivityextendsContextThemeWrapper
- implementsLayoutInflater.Factory,
- Window.Callback,KeyEvent.Callback,
- OnCreateContextMenuListener,ComponentCallbacks{
- ......
- publicbooleandispatchKeyEvent(KeyEventevent){
- ......
- Viewdecor=mDecor;
- if(decor==null)decor=win.getDecorView();
- returnevent.dispatch(this,decor!=null
- ?decor.getKeyDispatcherState():null,this);
- }
- ......
- }
Step 35. KeyEvent.dispatch
这个函数定义在frameworks/base/core/java/android/view/KeyEvent.java文件中:
- publicclassKeyEventextendsInputEventimplementsParcelable{
- ......
- publicfinalbooleandispatch(Callbackreceiver,DispatcherStatestate,
- Objecttarget){
- switch(mAction){
- caseACTION_DOWN:{
- ......
- booleanres=receiver.onKeyDown(mKeyCode,this);
- ......
- returnres;
- }
- caseACTION_UP:
- ......
- returnreceiver.onKeyUp(mKeyCode,this);
- caseACTION_MULTIPLE:
- finalintcount=mRepeatCount;
- finalintcode=mKeyCode;
- if(receiver.onKeyMultiple(code,count,this)){
- returntrue;
- }
- ......
- returnfalse;
- }
- returnfalse;
- }
- ......
- }
Activity窗口处理完这个键盘事件后,层层返回,最后回到Step 32中,调用finishInputEvent事件来处理一些手尾工,下面我们将会看到这些手尾工是什么。
更多相关文章
- C语言函数以及函数的使用
- Android探索之旅(第二十一篇)Android中事件冲突的解决收集(持续收录
- Android 自定义键盘中禁用点击预览弹窗
- android 不自动弹出虚拟键盘
- android-EditText输入框被键盘遮挡问题解决方案
- Android不让弹出键盘挡住View
- Android 仿微信的键盘切换
- [Android Studio] Android Studio如何提示函数用法
- Android交互体验必知:功能按键事件