Android webkit keyevent 事件传递过程

前言:基于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);

此时调用进入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)

原文发表时间:2015-03-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(55)-工作流设计-表单布局

前言:这一节比较有趣。基本纯UI,但是不是很复杂 有了实现表单的打印和更加符合流程表单方式,我们必须自定义布局来适合业务场景打印!我们想要什么效果?看下图 (我...

1689
来自专栏我和未来有约会

建立可扩展的silverlight 应用框架 step-6

整理导航模块“LeftNav” 首先说一下我想要实现的效果。 我希望在左侧的导航点击了以后右侧的主体部分发声变化。 之前我在LeftNav模块用的控件是Togg...

19710
来自专栏三流程序员的挣扎

Flutter 学习记2 - 首个应用

void main() 是入口方法,=> 用于单行方法,就是函数签名和函数体间的连接符号,感觉作用和 Kotlin 的单行函数体用 = 类似。既然这样,把代码修...

911
来自专栏大内老A

ASP.NET MVC的Razor引擎:RazorViewEngine

基于Web Form引擎的WebFormViewEngine和针对Razor引擎的RazorViewEngine都是抽象类型BuildManagerViewEn...

1949
来自专栏禁心尽力

XML技术之DOM4J解析器

由于DOM技术的解析,存在很多缺陷,比如内存溢出,解析速度慢等问题,所以就出现了DOM4J解析技术,DOM4J技术的出现大大改进了DOM解析技术的缺陷。 使用D...

1855
来自专栏刘望舒

APK是如何被解析的?

在本系列的前面文章中,我介绍了PackageInstaller的初始化和安装APK过程、PMS处理APK的安装和PMS的创建过程,这些文章中经常会涉及到一个类,...

823
来自专栏超然的博客

HTML5 data-* 自定义属性

  在HTML5中添加了data-*的方式来自定义属性,所谓data-*实际上上就是data-前缀加上自定义的属性名,使用这样的结构可以进行数据存放。使用dat...

912
来自专栏葡萄城控件技术团队

根据数据源字段动态设置报表中的列数量以及列宽度

在报表系统中,我们通常会有这样的需求,就是由用户来决定报表中需要显示的数据,比如数据源中共有八列数据,用户可以自己选择在报表中显示哪些列,并且能够自动调整列的宽...

19410
来自专栏IMWeb前端团队

Zepto源码分析之form模块

前言 JavaScript最初的一个应用场景就是分担服务器处理表单的责任,打破处处依赖服务器的局面,这篇文章主要介绍zepto中form模块关于表单处理的几个...

18210
来自专栏青玉伏案

iOS开发之窥探UICollectionViewController(一) -- Ready Your CollectionViewController

之前用CollectionViewController只是皮毛,一些iOS从入门到精通的书上也是泛泛而谈。这几天好好的搞了搞苹果的开发文档上Collection...

1776

扫码关注云+社区