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 条评论
登录 后参与评论

相关文章

来自专栏坚毅的PHP

困扰我多年的Connection reset问题

第一次出现:是thrift的python client去请求server,发现偶尔出现这个问题 第二次:接入第三方的api,去请求数据时,发现一个接入方的api...

3.9K6
来自专栏Zephery

谈谈个人网站的建立(八)—— 缓存的使用

一、概述 1.1 缓存介绍 系统的性能指标一般包括响应时间、延迟时间、吞吐量,并发用户数和资源利用率等。在应用运行过程中,我们有可能在一次数据库会话中,执行多次...

2985
来自专栏Android群英传

Google I/O 之 Android App Bundles 是个啥

2642
来自专栏比原链

剥开比原看代码07:比原节点收到“请求区块数据”的信息后如何应答?

Gitee地址:https://gitee.com/BytomBlockchain/bytom

832
来自专栏菩提树下的杨过

Flash/Flex学习笔记(53):利用FMS快速创建一个文本聊天室

先来看客户端fla的构成: 第一帧:登录界面 ? 第一帧的代码: import flash.events.MouseEvent; import com.adob...

1999
来自专栏Java3y

从零开始写项目第二篇【登陆注册、聊天、收藏夹模块】

登陆模块目标 我要将其弄成类似的登陆,功能是要比较完善的。 ? 本来我是想做一步写一步的,但是发现这样文章就会太乱,因为要改的地方太多了。前面写过的,后边就被修...

1.1K8
来自专栏程序员的碎碎念

JS动态加载以及JavaScript void(0)的爬虫解决方案

对于使用JS动态加载, 或者将下一页地址隐藏为 JavaScriptvoid(0)的网站, 如何爬取我们要的信息呢?

1182
来自专栏开源优测

RFC821 简单邮件传输协议(SMTP)

1243
来自专栏macOS 开发学习

macOS 应用开发小集锦

输出结果与当前app的语言环境有关(默认为English),如果需要修改工程的语言环境,需要设置Edit Scheme...

922
来自专栏nummy

Grunt快速入门

Grunt是基于JavaScript的命令行构建工具,它可以帮助开发者们自动化重复性的工作。你可以把它看成是JavaScript下的Make或者Ant。它可以完...

802

扫码关注云+社区