android源生Browser分析(三)---Framework層

Framework層的主要功能

Framework層的webkik主要起到提供給APP層一個WebView控件,WebSettings設置,WebViewClient回調,WebChromeClient回調。這些用於上層APP實現瀏覽網頁的功能。

而對於下層,通過native的接口與c++層的WebKit對接,把上層需求傳遞給WebKit,把WebKit的回調返回給上層或者自己做一些處理,因爲一些跟平臺相關的東西WebKit中也會回調到java層,讓java層做處理,比如上傳功能需要從其他模塊獲取上傳文件的資源。

在android 2.3及其之前的版本中,html頁面的請求是通過java層調用http接口來實現下載的,但是到了android4.0時html頁面的請求在c++的WebKit層直接通過chromium的net部分發送http請求了。這裏要額外注意的是,在android4.0中,對於java層的請求代碼仍然保留(實際上可以通過配置c++層的WebKit來恢復使用java層請求html)。所以android4.0上的framework層的webkit代碼是有些冗餘的。另外還添加了部分對html5的支持,這些部分暫時都不研究了。

幾個重要的類

WebView

WebView是提供給app層的控件,它必須運行在主線程也即UI線程中。

WebView中可以通過發消息給WebViewCore來請求功能,WebView中創建了CallbackProxy這個Handler的子類,用於讓其他線程發消息給WebView所在的主線程,可以實現其他功能線程回調請求給WebView.

WebViewCore

這裏要區分下WebViewCore類與WebViewCore線程。

WebViewCore類是與WebViewCore線程做交互的一個代理類,是WebView中創建的一個成員,用於讓WebView向WebViewCore線程發消息和WebViewCore線程回調信息給WebView用。

而WebViewCore線程則是個單例的線程,負責接收WebView發來的請求功能的消息,即功能請求從app發給WebView,WebView把請求發給WebViewCore線程,然後WebView就返回了,這樣不會影響到UI線程的阻塞。

其實這裏可以模糊掉WebViewCore類與WebViewCore線程的區別,可以認爲WebViewCore就是一個單獨的服務類,並且是個單例的(雖然事實不是這樣),模糊掉WebViewCore是WebView成員這個關係,認爲WebView就是向WebViewCore發消息來實現功能請求的就可以了,這樣就比較清晰他們的關係。

該類主要通過Message,Handler的機制在WebView與WebViewCore線程之間通訊的WebView向WebViewCore線程發的每個消息相當於一個請求的任務,而這個WebViewCore線程相當於一個服務,它在消息循環中不停的接收任務(消息),然後處理任務,然後再接收下一個任務(消息)。

基於這個模型可以把WebView看做客戶端,把WebViewCore線程看做服務端。雙方各自運行在各自的線程中,相互通過消息來通訊。

CallbackProxy

如上所說CallbackProxy 繼承自Handler,由WebView創建,用於讓其他線程的功能模塊回調信息給WebView所在的主線程的。CallbackProxy 把收到的消息具體分發到WebView,WebViewClient,WebChromeClient中。

BrowserFrame

BrowserFrame是在WebViewCore線程中創建的,並且是WebViewCore的成員,它對應c層WebKit的Frame,這個Frame是一個具體的頁面的概念。

BrowserFrame中也有CallbackProxy的引用,這樣可以通過CallbackProxy回調消息給WebView.

這幾個類的關係操作流程如下


但是這裏要注意,WebView,WebViewCore,BrowserFrame都是一對一的關係,即新建一個WebView都會建立對應的WebViewCore和BrowserFrame。同時在WebView中都有一個CallbackProxy。WebViewCore和BrowserFrame中也都有對應的CallbackProxy的引用。

而WebViewCore線程卻是全局唯一的一個。

這幾個類的組織關係如下


 

這幾個類的基本操作流程

可以看到很多操作都基於上述關係得到的流程,即請求先從APP發到WebView,在Framework層看來WebView是個客戶端,WebViewCore是個服務端,那麼請求會從WebView通過消息發給WebViewCore。WebViewCore會把處理通過自身的jni或者通過其成員BrowserFrame的jni發給C層的WebKit。

回調時,首先從C層的WebKit回調到WebViewCore或者BrowserFrame中,再通過成員引用CallbackProxy發消息給WebView所在的主線程,CallbackProxy中的消息處理中會決定把信息回調給WebView還是WebViewClient還是WebChromeClient。如果是後兩者則App中實現該接口,就會收到回調信息了(實際代碼中位於Tab.java中)。

這裏通過loadUrl的操作來看下上述的這個流程。

loadUrl的例子

App執行WebView的loadUrl接口。

WebView的loadUrl中把一些信息保存爲消息的參數,然後發出LOAD_URL消息給WebViewCore線程。以上完成了WebView向WebViewCore線程請求功能的過程。

接着WebViewCore線程收到消息,進行消息處理,對於LOAD_URL消息,首先取出消息中附帶的參數信息,然後交給成員BrowserFrame來處理。

BrowserFrame通過jni接口把功能請求傳遞到c層的WebKit中,由WebKit做具體的處理。以上完成了整個功能的請求過程。

接下來是回調流程,當頁面開始加載時首先在BrowserFrame中收到c層WebKit回調的函數loadStarted。此時回調操作是在WebViewCore線程中。

BrowserFrame通過CallbackProxy向主線程發消息PAGE_STARTED。以上完成了WebViewCore線程向WebView線程回調信息的過程。

CallbackProxy的消息處理循環位於主線程中,在消息處理函數中,分別向WebView和WebViewClient執行回調函數,其中WebViewClient執行的是onPageStarted回調函數。

WebViewClient本身定義成一套接口,在APP層實現了接口,所以APP層對WebViewClient實現的onPageStarted就會被調用,這樣APP層就收到了回調(實際代碼在Tab.java中)。以上便完成了整個功能的回調過程。

 

設置的流程

Framework 層提供的WebView的設置是WebSettings。但是WebSettings並不是在WebView中維護的,而是在WebViewCore中維護的。

WebSettings中有各個具體設置項的成員變量,

在app層進行WebSettings中某個設置項的設置後,如果該設置項的內容與之前的不同,則會用新的值來填充對應的成員變量,然後向WebViewCore線程發送消息SYNC,請求c層的WebKit同步設置內容。

讀取設置項時,就直接從成員變量中讀取就可以了。

 

Framework層與C層的 幾個主要的JNI類對應關係


發佈了20 篇原創文章 · 獲贊 11 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章