前言:基于android webview 上定制自己使用的可移植瀏覽器apk,遇到好多按鍵處理的問題。所以索性研究了一下keyevent 事件的傳遞流程。 frameworks 層 keyevent 事件開始是從/frameworks/base/core/java/android/webkit目錄下WebViewClassic.java 中的onKeyDown() 函數(shù)開始的 // Bubble up the key event if 這個的作用是判斷event是不是系統(tǒng)按鍵,或者調用webview應用處理event。系統(tǒng)按鍵直接返回, 如果webview應用處理了也直接返回。 其它key事件調用 sendKeyEvent(event),在sendKeyEvent() 又調用sendBatchableInputMessage() 在這個函數(shù)中又調用mWebViewCore.sendMessage(message) 將event封裝成Message傳遞給WebViewCore.java中的EventHub 類 在sendMessage()函數(shù)又通過它發(fā)送到Handler在transferMessages() 中handleMessage()處理keydown事件 case KEY_DOWN: webkit 對接層 key中調用nativeKey() 將事件傳入webkit中Source/WebKit/android/jni WebViewCore.cpp中的 { "nativeKey", "(IIIIZZZZ)Z", WebViewCore::key(const PlatformKeyboardEvent& event) eventHandler->keyEvent(event); WebCore對接層 此時調用進入Source/WebCore/page 中的EventHandler.cpp 它會區(qū)分為keyup keydown keypress 事件發(fā)送到Node中處理 bool Node::dispatchEvent(PassRefPtr<Event> 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中實現(xiàn)注冊監(jiān)聽 bool EventTarget::fireEventListeners(Event* event) registeredListener.listener->handleEvent(scriptExecutionContext(), event); 發(fā)送到注冊監(jiān)聽的javascript中。 如果在js中注冊了一個keypress事件處理而我們要兼容支持它我們可以只動WebViewClassic.java或者在app層代碼實現(xiàn)轉換并傳入js中即可。 在WebViewClassic.java中實現(xiàn)了passVirtualKeyEvent(int KeyCode)。 |
|
來自: wusiqi111 > 《webkit事件分發(fā)》