Android webkit 事件传递流程通道分析

前言:基于android webview 上定制本身使用的可移植浏览器apk,遇到好多按键处理的问题。因此索性研究了一下keyevent 事件的传递流程。javascript

frameworks 层java

keyevent 事件开始是从/frameworks/base/core/java/android/webkit目录下WebViewClassic.javanode

中的onKeyDown() 函数开始的android

          // Bubble up the key event if
          // 1. it is a system key; or
          // 2. the host application wants to handle it;
          if ((event.isSystem() || mCallbackProxy.uiOverrideKeyEvent(event))程序员

 这个的做用是判断event是否是系统按键,或者调用webview应用处理event。系统按键直接返回,web

若是webview应用处理了也直接返回。浏览器

其它key事件调用 sendKeyEvent(event),在sendKeyEvent() 又调用sendBatchableInputMessage()微信

在这个函数中又调用mWebViewCore.sendMessage(message)app

将event封装成Message传递给WebViewCore.java中的EventHub 类微信公众平台

在sendMessage()函数又经过它发送到Handler在transferMessages() 中handleMessage()处理keydown事件

          case KEY_DOWN:                                                                                                                 
                  key((KeyEvent) msg.obj, msg.arg1, true);
                  break;

webkit 对接层

key中调用nativeKey() 将事件传入webkit中Source/WebKit/android/jni WebViewCore.cpp中的

    { "nativeKey", "(IIIIZZZZ)Z",                                                                                                                     
        (void*) Key },

 

WebViewCore::key(const PlatformKeyboardEvent& event)

eventHandler->keyEvent(event); 

 

WebCore对接层

此时调用进入Source/WebCore/page 中的EventHandler.cpp

它会区分为keyup keydown keypress 事件发送到Node中处理

 bool Node::dispatchEvent(PassRefPtr<Event> event)
  {                
      return EventDispatcher::dispatchEvent(this, EventDispatchMediator(event));                                                   } 

经过中转最终调用到EventDispatcher.cpp中

bool EventDispatcher::dispatchEvent(PassRefPtr<Event> event)

m_node->handleLocalEvents(event.get());

在Node.cpp 中调用

fireEventListeners(event); 

class Node : public EventTarget  Node继承了EventTarget

EventTarget.cpp中实现注册监听

bool EventTarget::fireEventListeners(Event* event) 

 registeredListener.listener->handleEvent(scriptExecutionContext(), event); 

发送到注册监听的javascript中。

 

若是在js中注册了一个keypress事件处理而咱们要兼容支持它咱们能够只动WebViewClassic.java或者在app层代码实现转换并传入js中便可。

在WebViewClassic.java中实现了passVirtualKeyEvent(int KeyCode)。

 第一时间得到博客更新提醒,以及更多技术信息分享,欢迎关注我的微信公众平台:程序员互动联盟(coder_online),扫一扫下方二维码或搜索微信号coder_online便可关注,咱们能够在线交流。

                                                                  

相关文章
相关标签/搜索