日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

WebKit – WebKit For Android

 My鏡像站 2012-02-16

一、WebKit簡介

WebKit是一個開源的瀏覽器網(wǎng)頁排版引擎,包含WebCore排版引擎和JSCore引擎。
WebCore和JSCore引擎來自于KDE項目的KHTML和KJS開源項目。Android平臺的Web
引擎框架采用了WebKit項目中的WebCore和JSCore部分,上層由Java語言封裝,并且作
為API提供給Android應(yīng)用開發(fā)者,而底層使用WebKit核心庫(WebCore和JSCore)進(jìn)行
網(wǎng)頁排版。

二、WebKit目錄結(jié)構(gòu)

 

Android平臺的WebKit模塊分成JavaWebKit庫兩個部分,其目錄結(jié)構(gòu)如下表所示:

WebKit模塊目錄結(jié)構(gòu)

Java層(根目錄device/java/android/android/webkit

BrowserFrame.java

BrowserFrame對象是對WebCore庫中的Frame對象的Java層封裝,用于創(chuàng)建WebCore中定義的Frame,以及為該Frame對象提供Java層回調(diào)方法。

ByteArrayBuilder.java

ByteArrayBuilder輔助對象,用于byte塊鏈表的處理。

CachLoader.java

URL Cache載入器對象,該對象實現(xiàn)StreadLoader抽象基類,用于通過CacheResult對象載入內(nèi)容數(shù)據(jù)。

CacheManager.java

Cache管理對象,負(fù)責(zé)JavaCache對象管理

CacheSyncManager.java

Cache同步管理對象,負(fù)責(zé)同步RAMFLASH之間的瀏覽器Cache數(shù)據(jù)。實際的物理數(shù)據(jù)操作在WebSyncManager對象中完成。

CallbackProxy.java

該對象是用于處理WebCoreUI線程消息的代理類。當(dāng)有Web事件產(chǎn)生時WebCore線程會調(diào)用該回調(diào)代理類,代理類會通過消息的方式通知UI線程,并且調(diào)用設(shè)置的客戶對象的回調(diào)函數(shù)。

CellList.java

CellList定義圖片集合中的Cell,管理Cell圖片的繪制、狀態(tài)改變以及索引。

CookieManager.java

根據(jù)RFC2109規(guī)范,管理cookies

CookieSyncManager.java

Cookies同步管理對象,該對象負(fù)責(zé)同步RAMFlash之間的Cookies數(shù)據(jù)。實際的物理數(shù)據(jù)操作在基類WebSyncManager中完成。

DataLoader.java

數(shù)據(jù)載入器對象,用于載入網(wǎng)頁數(shù)據(jù)。

DateSorter.java

尚未使用

DownloadListener.java

下載偵聽器接口

DownloadManagerCore.java

下載管理器對象,管理下載列表。該對象運行在WebKit的線程中,通過CallbackProxy對象與UI線程交互。

FileLoader.java

文件載入器,將文件數(shù)據(jù)載入到Frame中。

FrameLoader.java

Frame載入器,用于載入網(wǎng)頁Frame數(shù)據(jù)

HttpAuthHandler.java

Http認(rèn)證處理對象,該對象會作為參數(shù)傳遞給BrowserCallback.displayHttpAuthDialog方法,與用戶交互。

HttpDataTime.java

該對象是處理HTTP日期的輔助對象。

JsConfirmResult.java

Js確認(rèn)請求對象

JsPromptResult.java

Js結(jié)果提示對象,用于向用戶提示Javascript運行結(jié)果。

JsResult.java

Js結(jié)果對象,用于用戶交互

JWebCoreJavaBridge.java

JavaWebCore庫中TimerCookies對象交互的橋接代碼。

LoadListener.java

載入器偵聽器,用于處理載入器偵聽消息。

Network.java

該對象封裝網(wǎng)絡(luò)連接邏輯,為調(diào)用者提供更為高級的網(wǎng)絡(luò)連接接口。

PanZoom.java

用于處理圖片縮放、移動等操作

PanZoomCellList.java

用于保存移動、縮放圖片的Cell

PerfChecker.java

用于效率測試的功能對象???

SslErrorHandler.java

用于處理SSL錯誤消息。

StreamLoader.java

StreamLoader抽象類是所有內(nèi)容載入器對象的基類。該類是通過消息方式控制的狀態(tài)機,用于將數(shù)據(jù)載入到Frame中。

TextDialog.java

用于處理html中文本區(qū)域疊加情況,可以使用標(biāo)準(zhǔn)的文本編輯而定義的特殊EditText控件。

URLUtil.java

URL處理功能函數(shù),用于編碼、解碼URL字符串,以及提供附加的URL類型分析功能。

WebBackForwardList.java

該對象包含WebView對象中顯示的歷史數(shù)據(jù)。

WebBackForwardListClient.java

瀏覽歷史處理的客戶接口類,所有需要接收瀏覽歷史改變的類都需要實現(xiàn)該接口。

WebChromeClient.java

Chrome客戶基類,Chrome客戶對象在瀏覽器文檔標(biāo)題、進(jìn)度條、圖標(biāo)改變時候會得到通知。

WebHistoryItem.java

該對象用于保存一條網(wǎng)頁歷史數(shù)據(jù)

WebIconDataBase.java

圖表數(shù)據(jù)庫管理對象,所有的WebView均請求相同的圖標(biāo)數(shù)據(jù)庫對象。

WebSettings.java

WebView的管理設(shè)置數(shù)據(jù),該對象數(shù)據(jù)是通過JNI接口從底層獲取。

WebSyncManager.java

數(shù)據(jù)同步對象,用于RAM數(shù)據(jù)和FLASH數(shù)據(jù)的同步操作。

WebView.java

Web視圖對象,用于基本的網(wǎng)頁數(shù)據(jù)載入、顯示等UI操作。

WebViewClient.java

Web視圖客戶對象,在Web視圖中有事件產(chǎn)生時,該對象可以獲得通知。

WebViewCore.java

該對象對WebCore庫進(jìn)行了封裝,將UI線程中的數(shù)據(jù)請求發(fā)送給WebCore處理,并且通過CallbackProxy的方式,通過消息通知UI線程數(shù)據(jù)處理的結(jié)果。

WebViewDatabase.java

該對象使用SQLiteDatabaseWebCore模塊提供數(shù)據(jù)存取操作。

 

三、WebKit模塊框架

Android平臺的WebKit模塊由Java層和WebKit庫兩個部分組成,Java層負(fù)責(zé)與Android應(yīng)用程序進(jìn)行通信,而WebKit類庫負(fù)責(zé)實際的網(wǎng)頁排版處理。Java層和C層庫之間通過JNIBridge相互調(diào)用,如下圖所示:

 

 

 

3.1 Java層框架

3.1.1 主要類關(guān)系

WebKit模塊的Java層一共由41個文件組成,其中主要的類關(guān)系如下圖所示:

 

  1. WebView

WebView類是WebKit模塊Java層的視圖類,所有需要使用Web瀏覽功能的Android應(yīng)用程序都要創(chuàng)建該視圖對象顯示和處理請求的網(wǎng)絡(luò)資源。目前,WebKit模塊支持HTTP、HTTPS、FTP以及javascript請求。WebView作為應(yīng)用程序的UI接口,為用戶提供了一系列的網(wǎng)頁瀏覽、用戶交互接口,客戶程序通過這些接口訪問WebKit核心代碼。

 

  1. WebViewDatabase

WebViewDatabaseWebKit模塊中針對SQLiteDatabase對象的封裝,用于存儲和獲取運行時瀏覽器保存的緩沖數(shù)據(jù)、歷史訪問數(shù)據(jù)、瀏覽器配置數(shù)據(jù)等。該對象是一個單實例對象,通過getInstance方法獲取WebViewDatabase的實例。WebViewDatabaseWebKit模塊中的內(nèi)部對象,僅供WebKit框架內(nèi)部使用。

 

  1. WebViewCore

WebViewCore類是Java層與CWebKit核心庫的交互類,客戶程序調(diào)用WebView的網(wǎng)頁瀏覽相關(guān)操作會轉(zhuǎn)發(fā)給BrowserFrame對象。當(dāng)WebKit核心庫完成實際的數(shù)據(jù)分析和處理后會回調(diào)WebViweCore中定義的一系列JNI接口,這些接口會通過CallbackProxy將相關(guān)事件通知相應(yīng)的UI對象。

 

  1. CallbackProxy

CallbackProxy是一個代理類,用于UI線程和WebCore線程交互。該類定義了一系列與用戶相關(guān)的通知方法,當(dāng)WebCore完成相應(yīng)的數(shù)據(jù)處理,則會調(diào)用CallbackProxy類中對應(yīng)的方法,這些方法通過消息方式間接調(diào)用相應(yīng)處理對象的處理方法。詳細(xì)的處理流程在下文中會具體分析。

 

  1. BrowserFrame

BrowserFrame類負(fù)責(zé)URL資源的載入、訪問歷史的維護(hù)、數(shù)據(jù)緩存等操作,該類會通過JNI接口直接與WebKit C層庫交互。

 

  1. JWebCoreJavaBridge

該類為JavaWebKit代碼提供與CWebKit核心部分的TimerCookies操作相關(guān)的方法。

 

  1. DownloadManagerCore

下載管理核心類,該類負(fù)責(zé)管理網(wǎng)絡(luò)資源下載,所有的Web下載操作均有該類同一管理。該類實例運行在WebKit線程當(dāng)中,與UI線程的交互是通過調(diào)用CallbackProxy對象中相應(yīng)的方法完成。

 

  1. WebSettings

該對象描述了WEB瀏覽器訪問相關(guān)的用戶配置信息。

 

  1. DownloadListener

下載偵聽接口,如果客戶代碼實現(xiàn)該接口,則在下載開始、失敗、掛起、完成等情況下,DownloadManagerCore對象會調(diào)用客戶代碼中實現(xiàn)的DwonloadListener方法。

 

  1. WebBackForwardList

WebBackForwarList對象維護(hù)著用戶訪問歷史記錄,該類為客戶程序提供操作訪問瀏覽器歷史數(shù)據(jù)的相關(guān)方法。

 

  1. WebViewClient

WebViewClient類定義了一系列事件方法,如果Android應(yīng)用程序設(shè)置了WebViewClient派生對象,則在頁面載入、資源載入、頁面訪問錯誤等情況發(fā)生時,該派生對象的相應(yīng)方法會被調(diào)用。

 

  1. WebBackForwardListClient

WebBackForwardListClient對象定義了對訪問歷史操作時可能產(chǎn)生的事件接口,當(dāng)用戶實現(xiàn)了該接口,則在操作訪問歷史時(訪問歷史移除、訪問歷史清空等)用戶會得到通知。

 

  1. WebChromeClient

WebChromeClient類定義了與瀏覽窗口修飾相關(guān)的事件。例如接收到Title、接收到Icon、進(jìn)度變化時,WebChromeClient的相應(yīng)方法會被調(diào)用。

 

3.1.2 主要類的設(shè)計

3.1.2.1 數(shù)據(jù)載入器的設(shè)計

WebKit模塊的Java部分框架中使用數(shù)據(jù)載入器來加載相應(yīng)類型的數(shù)據(jù),目前有CacheLoaderDataLoader以及FileLoader三類載入器,他們分別用于處理緩存數(shù)據(jù)、內(nèi)存據(jù),以及文件數(shù)據(jù)的載入操作。Java層(WebKit模塊)所有的載入器都從StreamLoader繼承(其父類為Handler),由于StreamLoader類的基類為Handler類,因此在構(gòu)造載入器時,會開啟一個事件處理線程,該線程負(fù)責(zé)實際的數(shù)據(jù)載入操作,而請求線程通過消息的方式驅(qū)動數(shù)據(jù)的載入。下圖是數(shù)據(jù)載入器相關(guān)類的類圖結(jié)構(gòu):

StreamLoader類定義了4個不同的消息(MSG_STATUS、MSG_HEADERS、MSG_DATA、MSG_END),分別表示發(fā)送狀態(tài)消息、發(fā)送消息頭消息、發(fā)送數(shù)據(jù)消息以及數(shù)據(jù)發(fā)送完畢消息。該類提供了2個抽象保護(hù)方法以及一個共有方法:setupStreamAndSendStatus保護(hù)方法主要是用于構(gòu)造與通信協(xié)議相關(guān)的數(shù)據(jù)流,以及向LoadListener發(fā)送狀態(tài)。buildHeaders方法是向子類提供構(gòu)造特定協(xié)議消息頭功能。所有載入器只有一個共有方法(load),因此當(dāng)需要載入數(shù)據(jù)時,調(diào)用該方法即可。與數(shù)據(jù)載入流程相關(guān)的類還有LoaderListener以及BrowserFrame,當(dāng)數(shù)據(jù)載入事件發(fā)生時, WebKit C庫會更新載入進(jìn)度,并且會通知BrowserFrame,BroserFrame接收到進(jìn)度條變更事件后會通過CallbackProxy對象,通知View類進(jìn)度條數(shù)據(jù)變更。下面以DataLoader類為例子,說明數(shù)據(jù)載入以及與UI交互過程:

上圖中綠色部分是BrowserFrame處理進(jìn)度變更事件時,調(diào)用CallbackProxy對象通知視圖變更狀態(tài)的操作,在這里省略。途中灰色部分表示C層代碼,而白色部分表示Java層代碼。

3.2 C層框架

3.2.1 C類與Java類的關(guān)系

1BrowserFrame

BrowserFrame Java類相對應(yīng)的C++類為FrameBridge,該類為Dalvik虛擬機回調(diào)BrowserFrame類中定義的本地方法進(jìn)行了封裝。與BrowserFrame中回調(diào)函數(shù)(Java層)相對應(yīng)的C層結(jié)構(gòu)定義如下:

該結(jié)構(gòu)作為FrameBridgeC層)的一個成員變量(mJavaFrame),在FrameBridge構(gòu)造函數(shù)中,用BrowserFrameJava層)類的回調(diào)方法的偏移量初始化JavaBrowserFrame結(jié)構(gòu)的各個域。初始后,當(dāng)WebCoreC層)在剖析網(wǎng)頁數(shù)據(jù)時,有Frame相關(guān)的資源改變,比如WEB頁面的主題變化,則會通過mJavaFrame結(jié)構(gòu),調(diào)用指定BrowserFrame對象的相應(yīng)方法,通知Java層處理。

 

2JWebCoreJavaBridge

與該對象相對應(yīng)的C層對象為JavaBridge,JavaBridge對象繼承了TimerClientCookieClient類,負(fù)責(zé)WebCore中的定時器和Cookie管理。與JavaJWebCoreJavaBridge類中方法偏移量相關(guān)的是JavaBridege中幾個成員變量,在構(gòu)造JavaBridge對象時,會初始化這些成員變量,之后有Timer或者Cookies事件產(chǎn)生,WebCore會通過這些ID值,回調(diào)對應(yīng)JWebCoreJavaBridge的相應(yīng)方法。

 

3LoadListener

與該對象相關(guān)的C層結(jié)構(gòu)是struct resourceloader_t,該結(jié)構(gòu)保存了LoadListener對象IDCancelMethod ID以及DownloadFiledMethod ID值。當(dāng)有Cancel或者Download事件產(chǎn)生,WebCore會回調(diào)LoadListener類中的CancelMethod或者DownloadFileMethod

 

4WebViewCore

WebViewCore相關(guān)的C類是WebCoreViewImpl,WebViewCoreImpl類有個JavaGlue對象作為成員變量,在構(gòu)建WebCoreViewImpl對象時,用WebViewCoreJava層)中的方法ID值初始化該成員變量。并且會將構(gòu)建的WebCoreViewImpl對象指針復(fù)制給WebViewCoreJava層)的mNativeClass,這樣將WebViewCoreJava層)和WebViewCoreImpleC層)關(guān)聯(lián)起來。

 

5WebSettings

WebSettings相關(guān)的C層結(jié)構(gòu)是struct FieldIds,該結(jié)構(gòu)保存了WebSettings類中定義的屬性ID以及方法ID,在WebCore初始化時(WebViewCore的靜態(tài)方法中使用System.loadLibrary載入)會設(shè)置這些方法和屬性的ID值。

 

6WebView

WebView相關(guān)的C層類是WebViewNative,該類中的mJavaGlue中保存著WebView中定義的屬性和方法ID,在WebViewNative構(gòu)造方法中初始化,并且將構(gòu)造的WebViewNative對象的指針,賦值給WebView類的mNativeClass變量,這樣WebViewWebViewNative對象建立了關(guān)系。

 

3.2.2 主要類關(guān)系

Java層相關(guān)的C層類如下表所示:

功能描述

ChromeClientAndroid

該類主要處理WebCore中與Frame裝飾相關(guān)的操作。例如設(shè)置狀態(tài)欄、滾動條、Javascript腳本提示框等。當(dāng)瀏覽器中有相關(guān)事件產(chǎn)生,ChromeClientAndroid類的相應(yīng)方法會被調(diào)用,該類會將相關(guān)的UI事件通過Bridge傳遞給Java層,由Java層負(fù)責(zé)繪制以及用戶交互方面的處理。

EditorClientAndroid

該類負(fù)責(zé)處理頁面中文本相關(guān)的處理,比如文本輸入、取消、輸入法數(shù)據(jù)處理、文本黏貼、文本編輯等操作。不過目前該類只對按鍵相關(guān)的時間進(jìn)行了處理,其他操作均未支持。

ContextMenuClient

該類提供頁面相關(guān)的功能菜單,比如圖片拷貝、朗讀、查找等功能。但是,目前項目中未實現(xiàn)具體功能。

DragClient

該類定義了與頁面拖拽相關(guān)的處理,但是目前該類沒有實現(xiàn)具體功能。

FrameLoaderClientAndroid

該類提供與Frame加載相關(guān)的操作,當(dāng)用戶請求加載一個頁面時,WebCore分析完網(wǎng)頁數(shù)據(jù)后,會通過該類調(diào)用Java層的回調(diào)方法,通知UI相關(guān)的組件處理。

InspectorClientAndroid

該類提供與窗口相關(guān)的操作,比如窗口顯示、關(guān)閉窗口、附加窗口等。不過目前該類的各個方法均為空實現(xiàn)。

Page

該類提供與頁面相關(guān)的操作,比如網(wǎng)頁頁面的前進(jìn)、后退等操作。

FrameAndroid

該類為Android提供Frame管理。

FrameBridge

該類對Frame相關(guān)的Java層方法進(jìn)行了封裝,當(dāng)有Frame事件產(chǎn)生時,WebCore通過FrameBridge回調(diào)Java的回調(diào)函數(shù),完成用戶交互過程。

AssetManager

該類為瀏覽器提供本地資源訪問功能。

RenderSkinAndroid

該類與控件繪制相關(guān),所有的須繪制控件都需要從該類派生,目前WebKit模塊中有ButtonCombo、Radio三類控件。

以上幾個類會在Java層請求創(chuàng)建Web Frame的時候被建立,他們的關(guān)系如下圖所示:

上圖中標(biāo)注為深綠色的FrameAndroid是瀏覽器Frame,一個BrowserFrame對象對應(yīng)著一個FrameAndroid對象。而其他8個標(biāo)注為淡綠色的類,是與該Frame顯示、布局等相關(guān)的類。WebKit模塊中所有WebCore核心代碼與用戶交互的操作使用FrameAndroid對象中的Bridge處理(回調(diào)相應(yīng)的Java方法)。

 

 

四、基本操作分析

4.1 WebKit模塊初始化

Android SDK中提供了WebView類,該類為客戶提供客戶化瀏覽顯示的功能,如果客戶需要加入瀏覽器的支持,可將該類的實例或者派生類的實例作為視圖,調(diào)用Activity類的setContentView顯示給用戶。當(dāng)客戶代碼中生成第一次生成WebView對象時,會初始化WebKit庫(包括Java層和C層兩個部分),之后用戶可以操作WebView對象完成網(wǎng)絡(luò)或者本地資源的訪問。

WebView對象的生成主要涉及3個類CallbackProxy、WebViewCore以及WebViewDatabase。其中CallbackProxy對象為WebKit模塊中UI線程和WebKit類庫提供交互功能,WebViewCoreWebKit的核心層,負(fù)責(zé)與C層交互以及WebKit模塊C層類庫初始化,而WebViewDatabaseWebKit模塊運行時緩存、數(shù)據(jù)存儲提供支持。WebKit模塊初始化流程如下:

WebView

+–創(chuàng)建CallbackProxy對象

+–創(chuàng)建WebViewCore對象

1–調(diào)用System.loadLibrary載入webcore相關(guān)類庫(C層)

2–如果是第一次初始化WebViewCore對象,創(chuàng)建WebCoreTherad線程

3–創(chuàng)建EventHub對象,處理WebViewCore事件

4–獲取WebIconDatabase對象實例

5–WebCoreThread發(fā)送初始化消息

+–獲取WebViewDatabase實例

如上所敘,第一步調(diào)用System.loadLibrary方法載入webcore相關(guān)類庫,該過程由Dalvik虛擬機完成,它會從動態(tài)鏈接庫目錄中尋找libWebCore.so類庫,載入到內(nèi)存中,并且調(diào)用WebKit初始化模塊的JNI_OnLoad方法。WebKit模塊的JNI_OnLoad方法中完成了如下初始化操作:

a) 初始化framebridge[register_android_webcore_framebridge]

初始化gFrameAndroidField靜態(tài)變量,以及注冊BrowserFrame類中的本地方法表。

b) 初始化javabridge[register_android_webcore_javabridge]

初始化gJavaBridge.mObject對象,以及注冊JWebCoreJavaBridge類中的本地方法

c) 初始化資源loader[register_android_webcore_resource_loader]

初始化gResourceLoader靜態(tài)變量,以及注冊LoadListener類的本地方法

d) 初始化webviewcore[register_android_webkit_webviewcore]

初始化gWebCoreViewImplField靜態(tài)變量,以及注冊WebViewCore類的本地方法

e) 初始化webhistory[register_android_webkit_webhistory]

初始化gWebHistoryItem結(jié)構(gòu),以及注冊WebBackForwardListWebHistoryItem類的本地方法

f) 初始化webicondatabase[register_android_webkit_webicondatabase]

注冊WebIconDatabase類的本地方法

g) 初始化websettings[register_android_webkit_websettings]

初始化gFieldIds靜態(tài)變量,以及注冊WebSettings類的本地方法

h) 初始化webview[register_android_webkit_webview]

初始化gWebViewNativeField靜態(tài)變量,以及注冊WebView類的本地方法

第二步是WebCoreThread初始化,該初始化只在第一次創(chuàng)建WebViewCore對象時完成,當(dāng)用戶代碼第一次生成WebView對象,會在初始化WebViewCore類時創(chuàng)建WebCoreThread線程,該線程負(fù)責(zé)處理WebCore初始化事件。此時WebViewCore構(gòu)造函數(shù)會被阻塞,直到一個WebView初始化請求完畢時,會在WebCoreThread線程中喚醒。

第三步創(chuàng)建EventStub對象,該對象處理WebView類的事件,當(dāng)WebCore初始化完成后會向WebView對象發(fā)送事件,WebView類的EventStub對象處理該事件,并且完成后續(xù)初始化工作。

第四步獲取WebIconDatabase對象實例。

第五步向WebViewCore發(fā)送INITIALIZE事件,并且將this指針作為消息內(nèi)容傳遞。WebView類主要負(fù)責(zé)處理UI相關(guān)的事件,而WebViewCore主要負(fù)責(zé)與WebCore庫交互。在運行時期,UI線程和WebCore數(shù)據(jù)處理線程是運行在兩個獨立的線程當(dāng)中。WebCoreThread線程接收到INITIALIZE線程后,會調(diào)用消息對象參數(shù)的initialize方法,而后喚醒阻塞的WebViewCore Java線程(該線程在WebViewCore的構(gòu)造函數(shù)中被阻塞)。不同的WebView對象實例有不同的WebViewCore對象實例,因此通過消息的方式可以使得UI線程和WebViewCore線程解耦合。WebCoreThread的事件處理函數(shù),處理INITIALIZE消息時,調(diào)用的是不同WebViewWebViewCore實例的initialize方法。WebViewCore類中的initialize方法中會創(chuàng)建BrowserFrame對象(該對象管理整個WEB窗體,以frame相關(guān)事件),并且向WebView對象發(fā)送WEBCORE_INITIALIZED_MSG_ID消息。WebView消息處理函數(shù),會根據(jù)消息參數(shù)1初始化指定的WebViewCore對象,并且更新WebViewCoreFrame緩沖。

初始化過程的序列圖如下圖所示:

初始化完成后Java層和C層類圖關(guān)系如下圖所示

上圖中淡綠色的類表示Java層,而灰色類表示C層。

4.2 數(shù)據(jù)載入

4.2.1 載入網(wǎng)絡(luò)數(shù)據(jù)

客戶代碼中可以使用WebView類的loadUrl方法,請求訪問指定的URL網(wǎng)頁數(shù)據(jù)。WebView對象中保存著WebViewCore的引用,由于WebView屬于UI線程,而WebViewCore屬于后臺線程,因此WebView對象的loadUrl被調(diào)用時,會通過消息的方式將URL信息傳遞給WebViewCore對象,該對象會調(diào)用成員變量mBrowserFrameloadUrl方法,進(jìn)而調(diào)用WebKit庫完成數(shù)據(jù)的載入。其調(diào)用函數(shù)序列如下所示:

網(wǎng)絡(luò)數(shù)據(jù)的載入分別由Java層和C層共同完成,Java層完成用戶交互、資源下載等操作,而C層主要完成數(shù)據(jù)分析(建立DOM樹、分析頁面元素等)操作。由于UI線程和WebCore線程運行在不同的兩個線程中,因此當(dāng)用戶請求訪問網(wǎng)絡(luò)資源時,通過消息的方式向WebViewCore對象發(fā)送載入資源請求。在Java層的WebKit模塊中,所有與資源載入相關(guān)的操作都是由BrowserFrame類中對應(yīng)的方法完成,這些方法是本地方法,會直接調(diào)用WebCore庫的C層函數(shù)完成數(shù)據(jù)載入請求,以及資源分析等操作。如上圖所示,C層的FrameLoader類是瀏覽框架的資源載入器,該類負(fù)責(zé)檢查訪問策略以及向Java層發(fā)送下載資源請求等功能。在FrameLoader中,當(dāng)用戶請求網(wǎng)絡(luò)資源時,經(jīng)過一系列的策略檢查后會調(diào)用FrameBridgestartLoadingResource方法,該方法會回調(diào)BrowserFrameJava)類的startLoadingResource方法,完成網(wǎng)絡(luò)數(shù)據(jù)的下載,而后BrowserFrameJava)類的startLoadingResource方法會返回一個LoadListener的對象,FrameLoader會刪除原有的FrameLoader對象,將LoadListener對象封裝成ResourceLoadHandler對象,并且將其設(shè)置為新的FrameLoader。到此完成了一次資源訪問請求,接下來的任務(wù)即是WebCore庫會根據(jù)資源數(shù)據(jù)進(jìn)行分析和構(gòu)建DOM,以及相關(guān)的數(shù)據(jù)結(jié)構(gòu)。

4.2.2 載入本地數(shù)據(jù)

本地數(shù)據(jù)是以data://開頭的URL表示,載入過程和網(wǎng)絡(luò)數(shù)據(jù)一樣,只不過在執(zhí)行FrameLoader類的executeLoad方法時,會根據(jù)URLSCHEME類型區(qū)分,調(diào)用DataLoaderrequestUrl方法(參看3.1.2.1節(jié)對載入器的分析),而不是調(diào)用handleHTTPLoad建立實際的網(wǎng)絡(luò)通信連接。

 

4.2.3 載入文件數(shù)據(jù)

文件數(shù)據(jù)是以file://開頭的URL,載入的基本流程與網(wǎng)絡(luò)數(shù)據(jù)載入流程基本一致,不同的是在運行FrameLoader類的executeLoad方法時,根據(jù)SCHEME類型,調(diào)用FileLoaderrequestUrl方法,完成數(shù)據(jù)加載(參看3.1.2.1節(jié)對載入器的分析)。

 

4.3 刷新繪制

當(dāng)用戶拖動滾動條、有窗口遮蓋、或者有頁面事件觸發(fā)都會向WebViewCoreJava層)對象發(fā)送背景重繪消息,該消息會引起網(wǎng)頁數(shù)據(jù)的繪制操作。WebKit的數(shù)據(jù)繪制可能出于效率上的考慮,沒有通過Java層,而是直接在C層使用SGL庫完成。與Java層圖形繪制相關(guān)的Java對象有如下幾個:

  1. Picture

該類對SGL封裝,其中變量mNativePicture實際上是保存著SkPicture對象的指針。WebViewCore中定義了兩個Picture對象,當(dāng)作雙緩沖處理,在調(diào)用webKitDraw方法時,會交換兩個緩沖區(qū),加速刷新速度。

  1. WebView

該類接受用戶交互相關(guān)的操作,當(dāng)有滾屏、窗口遮蓋、用戶點擊頁面按鈕等相關(guān)操作時,WebView對象會與之相關(guān)的WebViewCore對象發(fā)送VIEW_SIZE_CHANGED消息。當(dāng)WebViewCore對象接收到該消息后,將構(gòu)建時建立的mContentPictureB刷新到屏幕上,然后將mContentPictureA與之交換。

  1. WebViewCore

該類封裝了WebKit C層代碼,為視圖類提供對WebKit的操作接口,所有對WebKit庫的用戶請求均由該類處理,并且該類還為視圖類提供了兩個Picture對象,用于圖形數(shù)據(jù)刷新。

 

下面以Web頁面被鼠標(biāo)拖拽的情況為例子,分析網(wǎng)頁數(shù)據(jù)刷新過程。當(dāng)用戶使用手指點擊觸摸屏,并且移動手指,則會引發(fā)touch事件的產(chǎn)生,Android平臺會將touch事件傳遞給最前端的視圖相應(yīng)(dispatchTouchEvent方法處理)。在WebView類中定義了5touch模式,在手指拖動Web頁面的情況下,會觸發(fā)mMotionDragMode,并且會調(diào)用View類的scrollBy方法,觸發(fā)滾屏事件以及使視圖無效(重繪,會調(diào)用ViewonDraw方法)。WebView視圖中的滾屏事件由onScrollChanged方法響應(yīng),該方法向WebViewCore對象發(fā)送SET_VISIBLE_RECT事件。

WebViewCore對象接收到SET_VISIBLE_RECT事件后,將消息參數(shù)中保存的新視圖的矩形區(qū)域大小傳遞給nativeSetVisibleRect方法,通知WebCoreViewImpl對象(C層)視圖矩形變更(WebCoreViewImpl::setVisibleRect方法)。在setVisibleRect方法中,會通過虛擬機調(diào)用WebViewCorecontentInvalidate方法,該方法會引發(fā)webkitDraw方法的調(diào)用(通過WEBKIT_DRAW消息)。在webkitDraw方法里,首先會將mContentPictureB對象傳遞給本地方法nativeDraw繪制,而后將mContentPictureB的內(nèi)容與mContentPictureA的內(nèi)容對調(diào)。在這里mContentPictureA緩沖區(qū)是供給WebViewCoredraw方法使用,如果用戶選擇某個控件,繪制焦點框時候WebViewCore對象的draw方法會調(diào)用,繪制的內(nèi)容保存在mContentPictureA中,之后會通過Canvas對象(Java層)的drawPicture方法將其繪制到屏幕上,而mContentPictureB緩沖區(qū)是用于built操作的,nativeDraw方法中首先會將傳遞的mContentPictureB對象數(shù)據(jù)重置,而后在重新構(gòu)建的mContentPictureB畫布上,將層上相關(guān)的元素繪制到該畫布上。上面提到,之后會將mContentPictureBmContentPictureA的內(nèi)容對調(diào),這樣一次重繪事件產(chǎn)生時(會調(diào)用WebView.onDraw方法)會將mContentPictureA的數(shù)據(jù)使用Canvas類的drawPicture繪制到屏幕上。當(dāng)webkitDraw方法將mContentPictureAmContentPictureB指針對調(diào)后,會向WebView對象發(fā)送NEW_PICTURE_MSG_ID消息,該消息會引發(fā)WebViewCoreVIEW_SIZE_CHANGED消息的產(chǎn)生,并且會使當(dāng)前視圖無效產(chǎn)生重繪事件(invalidate()),引發(fā)onDraw方法的調(diào)用,完成一次網(wǎng)頁數(shù)據(jù)的繪制過程。

~~~ END ~~~

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多