Android WebKit訊息處理
前言
在Android API中,用WebView的形式向開發人員提供WebKit的介面以及特性。WebView其實是對WebKit的封裝以及擴充,在android4.4裡面,已經WebKit已經換成Chromium(在後續部落格中會對android4.4 的WebView/Chromium進行詳細講解)。
WebKit訊息處理架構的搭建
整個WebKit主要分為2個線程,一個是Ui線程,也就是應用程式使用WebView所在的主線程,另一個WebCore線程。WebView的訊息處理,主要是Ui線程和WebCore線程的互動。一部分Ui線程向WebCore發送的命令操作訊息,例如LOAD_URL,另一部分是來自Ui的touch訊息。
主要涉及到的類:
其中,WebViewClassic是WebView的Provider,或者說是delegate,凡是涉及到訊息處理或者需要跟WebCore互動的介面,都是直接調用WebViewClassic的同名函數。
WebViewInputDispatcher就是用來處理Ui的touch事件的。後面會專門講解WebKit的touch事件傳遞以及處理流程的。本章就不展開講解了。
WebView的初始化
時序圖如下:
其實就是WebView/WebKit的初始化流程,主要是對WebViewClassic, WebCore, WebViewInputDispatcher進行初始化,為WebKit資源請求前做準備。WebView建構函式中會調用createWebView,這個過程其實就是建立WebView的provider,實際返回的對象就是WebViewClassic,緊接著init初始化WebViewClassic,在WebViewClassic的init中會new WebViewCore(),之後對WebViewCore進行初始化,在WebViewCore自己初始化完畢之後,表明現在WebCore已經可以處理來自WebView的訊息了,包括touch事件,此時WebViewCore會發送訊息給WebViewClassic,也就是中看到的WEBCORE_INITIALIZED_MSG_ID,WebViewClassic收到此訊息之後,就會初始化touch事件的分發器:WebViewInputDispatcher。這個流程結束之後,應用就可以通過WebView,loadUrl了。
從這個圖中,我們看到,在WebCore的建構函式中會new WebCoreThread,這個線程就是上面提到的WebCore線程。到此為止,我們已經可以看到有2個線程了,一個是WebView所在的Ui線程,另一個就是WebCore線程。
那麼WebKit的訊息處理究竟怎麼工作的呢?
在WebView中,訊息線上程間的分發使用的是Handler。在WebKit的訊息分發機制中的總共有三個Handler如下:
mPrivateHandler:
在WebViewClassic中建立,用來分發和處理UI相關訊息,例如重繪,touch事件,另外就是負責跟WebCore線程互動。
sWebCoreHandler:
在WebCoreThread中間,主要負責WebViewCore初始化、WebViewCoreWatchDog心跳、WebCore線程優先順序別調整。
mHandler:
WebCore線程訊息迴圈最主要的handler。任何需要調用WebCore介面的,都需要通過mHandler send到WebCore線程中去。
在EventHub的transferMessages()中被new出來的,由於transferMessages()實在WebViweCore的initialize()中被調用的,所以,EventHub的mHandler也是
在WebCore線程中。
Ui線程第一次向WebCore線程發送的訊息,並沒有直接被分發到WebCore線程中去。而是被緩衝在WebViewCore中的mMessages list中,因為有可能在WebKit的訊息處理架構還未初始化完畢,Ui線程就已經開始向WebCore線程發送訊息了。所以,當WebViewCore最後初始化完畢之後,會調用transferMessages(),在transferMessages中將mMessages中的訊息通過mHandler全部send到WebCore線程中去。
到這裡已經應該很明白了:
Ui線程的訊息通過WebViewClassic的mPrivateHandler處理。
WebCore線程的訊息通過EventHub的mHandler和WebViewCore的sWebCoreHandler處理。各個Handler之間可以相互send訊息到對方的訊息佇列中去。
著作權申明:
轉載文章請註明原文出處,任何用於商業目的,請聯絡本人:hyman_tan@126.com