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

frameworks 层

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

中的onKeyDown() 函数开始的

// 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。系统按键直接返回,

如果webview应用处理了也直接返回。

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

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

将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即可关注,我们可以在线交流。

                                                                  

最新文章

  1. windows service 1053错误 启动失败
  2. eclipse里打开SWT项目找不到source/design的图形UI设计界面
  3. Js笔试题之parseInt()和.map()
  4. NGUI基础之button(按钮)
  5. TCP 3次握手和四次挥手
  6. HTML 事件
  7. NODE.JS玩玩
  8. C#图像处理(4):图像的剪裁
  9. 制作service服务,shell脚本小例子(来自网络)
  10. hiveQL求差集
  11. 对于多线程下Servlet以及Session的一些理解
  12. 几种线程安全的Map解析
  13. Ubuntu下使用git提交代码至GitHub
  14. BMDThread控件动态创建多线程示例
  15. ios开发UI篇--UILabel
  16. postgresql双机热备、高可用方案(采用pacemaker+corosync实现)
  17. PostgreSQL 常用的命令
  18. mysql-connector-java小笔记
  19. (转)MapReduce Design Patterns(chapter 2 (part 3))(四)
  20. Tencent Server Web 安装试用

热门文章

  1. Google的JSON风格指南
  2. IO 函数
  3. 简单、强大的swig.js
  4. NBUT 1457 Sona (莫队算法)
  5. 利用Loader来动态载入不同的QML文件来改变UI
  6. 怎样使用1M的内存排序100万个8位数
  7. lua 异常 错误处理 pcall
  8. VirtualBox中使用双网卡实现CentOS既能上网(校园网)也能使用SSHclient
  9. Objective C运行时(runtime)技术总结,好强大的runtime
  10. IE浏览器部分版本不支持background-size属性问题