如需轉載,請註明出處! WebSite: http://www.jjos.org/ 做者: 姜江 linuxemacs@gmail.com QQ: 457283javascript
這是一篇本身寫於一年前的工做文檔,分享出來。html
Android平臺的WebKit模塊分紅Java和WebKit庫兩個部分,其目錄結構以下表所示:前端
WebKit模塊目錄結構java |
|
Java層(根目錄device\java\android\android\webkit)linux |
|
BrowserFrame.javaandroid |
BrowserFrame對象是對WebCore庫中的Frame對象的Java層封裝,用於建立WebCore中定義的Frame,以及爲該Frame對象提供Java層回調方法。web |
ByteArrayBuilder.java數據庫 |
ByteArrayBuilder輔助對象,用於byte塊鏈表的處理。瀏覽器 |
CachLoader.java緩存 |
URL Cache載入器對象,該對象實現StreadLoader抽象基類,用於經過CacheResult對象載入內容數據。 |
CacheManager.java |
Cache管理對象,負責Java層Cache對象管理 |
CacheSyncManager.java |
Cache同步管理對象,負責同步RAM和FLASH之間的瀏覽器Cache數據。實際的物理數據操做在WebSyncManager對象中完成。 |
CallbackProxy.java |
該對象是用於處理WebCore與UI線程消息的代理類。當有Web事件產生時WebCore線程會調用該回調代理類,代理類會經過消息的方式通知UI線程,而且調用設置的客戶對象的回調函數。 |
CellList.java |
CellList定義圖片集合中的Cell,管理Cell圖片的繪製、狀態改變以及索引。 |
CookieManager.java |
根據RFC2109規範,管理cookies |
CookieSyncManager.java |
Cookies同步管理對象,該對象負責同步RAM和Flash之間的Cookies數據。實際的物理數據操做在基類WebSyncManager中完成。 |
DataLoader.java |
數據載入器對象,用於載入網頁數據。 |
DateSorter.java |
還沒有使用 |
DownloadListener.java |
下載偵聽器接口 |
DownloadManagerCore.java |
下載管理器對象,管理下載列表。該對象運行在WebKit的線程中,經過CallbackProxy對象與UI線程交互。 |
FileLoader.java |
文件載入器,將文件數據載入到Frame中。 |
FrameLoader.java |
Frame載入器,用於載入網頁Frame數據 |
HttpAuthHandler.java |
Http認證處理對象,該對象會做爲參數傳遞給BrowserCallback.displayHttpAuthDialog方法,與用戶交互。 |
HttpDataTime.java |
該對象是處理HTTP日期的輔助對象。 |
JsConfirmResult.java |
Js確認請求對象 |
JsPromptResult.java |
Js結果提示對象,用於向用戶提示Javascript運行結果。 |
JsResult.java |
Js結果對象,用於用戶交互 |
JWebCoreJavaBridge.java |
用Java與WebCore庫中Timer和Cookies對象交互的橋接代碼。 |
LoadListener.java |
載入器偵聽器,用於處理載入器偵聽消息。 |
Network.java |
該對象封裝網絡鏈接邏輯,爲調用者提供更爲高級的網絡鏈接接口。 |
PanZoom.java |
用於處理圖片縮放、移動等操做 |
PanZoomCellList.java |
用於保存移動、縮放圖片的Cell |
PerfChecker.java |
用於效率測試的功能對象??? |
SslErrorHandler.java |
用於處理SSL錯誤消息。 |
StreamLoader.java |
StreamLoader抽象類是全部內容載入器對象的基類。該類是經過消息方式控制的狀態機,用於將數據載入到Frame中。 |
TextDialog.java |
用於處理html中文本區域疊加狀況,可使用標準的文本編輯而定義的特殊EditText控件。 |
URLUtil.java |
URL處理功能函數,用於編碼、解碼URL字符串,以及提供附加的URL類型分析功能。 |
WebBackForwardList.java |
該對象包含WebView對象中顯示的歷史數據。 |
WebBackForwardListClient.java |
瀏覽歷史處理的客戶接口類,全部須要接收瀏覽歷史改變的類都須要實現該接口。 |
WebChromeClient.java |
Chrome客戶基類,Chrome客戶對象在瀏覽器文檔標題、進度條、圖標改變時候會獲得通知。 |
WebHistoryItem.java |
該對象用於保存一條網頁歷史數據 |
WebIconDataBase.java |
圖表數據庫管理對象,全部的WebView均請求相同的圖標數據庫對象。 |
WebSettings.java |
WebView的管理設置數據,該對象數據是經過JNI接口從底層獲取。 |
WebSyncManager.java |
數據同步對象,用於RAM數據和FLASH數據的同步操做。 |
WebView.java |
Web視圖對象,用於基本的網頁數據載入、顯示等UI操做。 |
WebViewClient.java |
Web視圖客戶對象,在Web視圖中有事件產生時,該對象能夠得到通知。 |
WebViewCore.java |
該對象對WebCore庫進行了封裝,將UI線程中的數據請求發送給WebCore處理,而且經過CallbackProxy的方式,經過消息通知UI線程數據處理的結果。 |
WebViewDatabase.java |
該對象使用SQLiteDatabase爲WebCore模塊提供數據存取操做。 |
Android平臺的WebKit模塊由Java層和WebKit庫兩個部分組成,Java層負責與Android應用程序進行通訊,而WebKit類庫負責實際的網頁排版處理。Java層和C層庫之間經過JNI和Bridge相互調用,以下圖所示:
WebKit模塊的Java層一共由41個文件組成,其中主要的類關係以下圖所示:
WebView
WebView類是WebKit模塊Java層的視圖類,全部須要使用Web瀏覽功能的Android應用程序都要建立該視圖對象顯示和處理請求的網絡資源。目前,WebKit模塊支持HTTP、HTTPS、FTP以及javascript請求。WebView做爲應用程序的UI接口,爲用戶提供了一系列的網頁瀏覽、用戶交互接口,客戶程序經過這些接口訪問WebKit核心代碼。
WebViewDatabase
WebViewDatabase是WebKit模塊中針對SQLiteDatabase對象的封裝,用於存儲和獲取運行時瀏覽器保存的緩衝數據、歷史訪問數據、瀏覽器配置數據等。該對象是一個單實例對象,經過getInstance方法獲取WebViewDatabase的實例。WebViewDatabase是WebKit模塊中的內部對象,僅供WebKit框架內部使用。
WebViewCore
WebViewCore類是Java層與C層WebKit核心庫的交互類,客戶程序調用WebView的網頁瀏覽相關操做會轉發給BrowserFrame對象。當WebKit核心庫完成實際的數據分析和處理後會回調WebViweCore中定義的一系列JNI接口,這些接口會經過CallbackProxy將相關事件通知相應的UI對象。
CallbackProxy
CallbackProxy是一個代理類,用於UI線程和WebCore線程交互。該類定義了一系列與用戶相關的通知方法,當WebCore完成相應的數據處理,則會調用CallbackProxy類中對應的方法,這些方法經過消息方式間接調用相應處理對象的處理方法。詳細的處理流程在下文中會具體分析。
BrowserFrame
BrowserFrame類負責URL資源的載入、訪問歷史的維護、數據緩存等操做,該類會經過JNI接口直接與WebKit C層庫交互。
JWebCoreJavaBridge
該類爲Java層WebKit代碼提供與C層WebKit核心部分的Timer和Cookies操做相關的方法。
DownloadManagerCore
下載管理核心類,該類負責管理網絡資源下載,全部的Web下載操做均有該類同一管理。該類實例運行在WebKit線程當中,與UI線程的交互是經過調用CallbackProxy對象中相應的方法完成。
WebSettings
該對象描述了WEB瀏覽器訪問相關的用戶配置信息。
DownloadListener
下載偵聽接口,若是客戶代碼實現該接口,則在下載開始、失敗、掛起、完成等狀況下,DownloadManagerCore對象會調用客戶代碼中實現的DwonloadListener方法。
WebBackForwardList
WebBackForwarList對象維護着用戶訪問歷史記錄,該類爲客戶程序提供操做訪問瀏覽器歷史數據的相關方法。
WebViewClient
WebViewClient類定義了一系列事件方法,若是Android應用程序設置了WebViewClient派生對象,則在頁面載入、資源載入、頁面訪問錯誤等狀況發生時,該派生對象的相應方法會被調用。
WebBackForwardListClient
WebBackForwardListClient對象定義了對訪問歷史操做時可能產生的事件接口,當用戶實現了該接口,則在操做訪問歷史時(訪問歷史移除、訪問歷史清空等)用戶會獲得通知。
WebChromeClient
WebChromeClient類定義了與瀏覽窗口修飾相關的事件。例如接收到Title、接收到Icon、進度變化時,WebChromeClient的相應方法會被調用。
WebKit模塊的Java部分框架中使用數據載入器來加載相應類型的數據,目前有CacheLoader、DataLoader以及FileLoader三類載入器,他們分別用於處理緩存數據、內存據,以及文件數據的載入操做。Java層(WebKit模塊)全部的載入器都從StreamLoader繼承(其父類爲Handler),因爲StreamLoader類的基類爲Handler類,所以在構造載入器時,會開啓一個事件處理線程,該線程負責實際的數據載入操做,而請求線程經過消息的方式驅動數據的載入。下圖是數據載入器相關類的類圖結構:
StreamLoader類定義了4個不一樣的消息(MSG_STATUS、MSG_HEADERS、MSG_DATA、MSG_END),分別表示發送狀態消息、發送消息頭消息、發送數據消息以及數據發送完畢消息。該類提供了2個抽象保護方法以及一個共有方法:setupStreamAndSendStatus保護方法主要是用於構造與通訊協議相關的數據流,以及向LoadListener發送狀態。buildHeaders方法是向子類提供構造特定協議消息頭功能。全部載入器只有一個共有方法(load),所以當須要載入數據時,調用該方法便可。與數據載入流程相關的類還有LoaderListener以及BrowserFrame,當數據載入事件發生時, WebKit C庫會更新載入進度,而且會通知BrowserFrame,BroserFrame接收到進度條變動事件後會經過CallbackProxy對象,通知View類進度條數據變動。下面以DataLoader類爲例子,說明數據載入以及與UI交互過程:
上圖中綠色部分是BrowserFrame處理進度變動事件時,調用CallbackProxy對象通知視圖變動狀態的操做,在這裏省略。途中灰色部分表示C層代碼,而白色部分表示Java層代碼。
1.BrowserFrame
與BrowserFrame Java類相對應的C++類爲FrameBridge,該類爲Dalvik虛擬機回調BrowserFrame類中定義的本地方法進行了封裝。與BrowserFrame中回調函數(Java層)相對應的C層結構定義以下:
該結構做爲FrameBridge(C層)的一個成員變量(mJavaFrame),在FrameBridge構造函數中,用BrowserFrame(Java層)類的回調方法的偏移量初始化JavaBrowserFrame結構的各個域。初始後,當WebCore(C層)在剖析網頁數據時,有Frame相關的資源改變,好比WEB頁面的主題變化,則會經過mJavaFrame結構,調用指定BrowserFrame對象的相應方法,通知Java層處理。
2.JWebCoreJavaBridge
與該對象相對應的C層對象爲JavaBridge,JavaBridge對象繼承了TimerClient和CookieClient類,負責WebCore中的定時器和Cookie管理。與Java層JWebCoreJavaBridge類中方法偏移量相關的是JavaBridege中幾個成員變量,在構造JavaBridge對象時,會初始化這些成員變量,以後有Timer或者Cookies事件產生,WebCore會經過這些ID值,回調對應JWebCoreJavaBridge的相應方法。
3.LoadListener
與該對象相關的C層結構是struct resourceloader_t,該結構保存了LoadListener對象ID、CancelMethod ID以及DownloadFiledMethod ID值。當有Cancel或者Download事件產生,WebCore會回調LoadListener類中的CancelMethod或者DownloadFileMethod。
4.WebViewCore
與WebViewCore相關的C類是WebCoreViewImpl,WebViewCoreImpl類有個JavaGlue對象做爲成員變量,在構建WebCoreViewImpl對象時,用WebViewCore(Java層)中的方法ID值初始化該成員變量。而且會將構建的WebCoreViewImpl對象指針複製給WebViewCore(Java層)的mNativeClass,這樣將WebViewCore(Java層)和WebViewCoreImple(C層)關聯起來。
5.WebSettings
與WebSettings相關的C層結構是struct FieldIds,該結構保存了WebSettings類中定義的屬性ID以及方法ID,在WebCore初始化時(WebViewCore的靜態方法中使用System.loadLibrary載入)會設置這些方法和屬性的ID值。
6.WebView
與WebView相關的C層類是WebViewNative,該類中的mJavaGlue中保存着WebView中定義的屬性和方法ID,在WebViewNative構造方法中初始化,而且將構造的WebViewNative對象的指針,賦值給WebView類的mNativeClass變量,這樣WebView和WebViewNative對象創建了關係。
與Java層相關的C層類以下表所示:
類 |
功能描述 |
ChromeClientAndroid |
該類主要處理WebCore中與Frame裝飾相關的操做。例如設置狀態欄、滾動條、Javascript腳本提示框等。當瀏覽器中有相關事件產生,ChromeClientAndroid類的相應方法會被調用,該類會將相關的UI事件經過Bridge傳遞給Java層,由Java層負責繪製以及用戶交互方面的處理。 |
EditorClientAndroid |
該類負責處理頁面中文本相關的處理,好比文本輸入、取消、輸入法數據處理、文本黏貼、文本編輯等操做。不過目前該類只對按鍵相關的時間進行了處理,其餘操做均未支持。 |
ContextMenuClient |
該類提供頁面相關的功能菜單,好比圖片拷貝、朗讀、查找等功能。可是,目前項目中未實現具體功能。 |
DragClient |
該類定義了與頁面拖拽相關的處理,可是目前該類沒有實現具體功能。 |
FrameLoaderClientAndroid |
該類提供與Frame加載相關的操做,當用戶請求加載一個頁面時,WebCore分析完網頁數據後,會經過該類調用Java層的回調方法,通知UI相關的組件處理。 |
InspectorClientAndroid |
該類提供與窗口相關的操做,好比窗口顯示、關閉窗口、附加窗口等。不過目前該類的各個方法均爲空實現。 |
Page |
該類提供與頁面相關的操做,好比網頁頁面的前進、後退等操做。 |
FrameAndroid |
該類爲Android提供Frame管理。 |
FrameBridge |
該類對Frame相關的Java層方法進行了封裝,當有Frame事件產生時,WebCore經過FrameBridge回調Java的回調函數,完成用戶交互過程。 |
AssetManager |
該類爲瀏覽器提供本地資源訪問功能。 |
RenderSkinAndroid |
該類與控件繪製相關,全部的須繪製控件都須要從該類派生,目前WebKit模塊中有Button、Combo、Radio三類控件。 |
以上幾個類會在Java層請求建立Web Frame的時候被創建,他們的關係以下圖所示:
上圖中標註爲深綠色的FrameAndroid是瀏覽器Frame,一個BrowserFrame對象對應着一個FrameAndroid對象。而其餘8個標註爲淡綠色的類,是與該Frame顯示、佈局等相關的類。WebKit模塊中全部WebCore核心代碼與用戶交互的操做使用FrameAndroid對象中的Bridge處理(回調相應的Java方法)。
Android SDK中提供了WebView類,該類爲客戶提供客戶化瀏覽顯示的功能,若是客戶須要加入瀏覽器的支持,可將該類的實例或者派生類的實例做爲視圖,調用Activity類的setContentView顯示給用戶。當客戶代碼中生成第一次生成WebView對象時,會初始化WebKit庫(包括Java層和C層兩個部分),以後用戶能夠操做WebView對象完成網絡或者本地資源的訪問。
WebView對象的生成主要涉及3個類CallbackProxy、WebViewCore以及WebViewDatabase。其中CallbackProxy對象爲WebKit模塊中UI線程和WebKit類庫提供交互功能,WebViewCore是WebKit的核心層,負責與C層交互以及WebKit模塊C層類庫初始化,而WebViewDatabase爲WebKit模塊運行時緩存、數據存儲提供支持。WebKit模塊初始化流程以下:
WebView
+–建立CallbackProxy對象
+–建立WebViewCore對象
1–調用System.loadLibrary載入webcore相關類庫(C層)
2–若是是第一次初始化WebViewCore對象,建立WebCoreTherad線程
3–建立EventHub對象,處理WebViewCore事件
4–獲取WebIconDatabase對象實例
5–向WebCoreThread發送初始化消息
+–獲取WebViewDatabase實例
如上所敘,第一步調用System.loadLibrary方法載入webcore相關類庫,該過程由Dalvik虛擬機完成,它會從動態連接庫目錄中尋找libWebCore.so類庫,載入到內存中,而且調用WebKit初始化模塊的JNI_OnLoad方法。WebKit模塊的JNI_OnLoad方法中完成了以下初始化操做:
a) 初始化framebridge[register_android_webcore_framebridge]
初始化gFrameAndroidField靜態變量,以及註冊BrowserFrame類中的本地方法表。
b) 初始化javabridge[register_android_webcore_javabridge]
初始化gJavaBridge.mObject對象,以及註冊JWebCoreJavaBridge類中的本地方法
c) 初始化資源loader[register_android_webcore_resource_loader]
初始化gResourceLoader靜態變量,以及註冊LoadListener類的本地方法
d) 初始化webviewcore[register_android_webkit_webviewcore]
初始化gWebCoreViewImplField靜態變量,以及註冊WebViewCore類的本地方法
e) 初始化webhistory[register_android_webkit_webhistory]
初始化gWebHistoryItem結構,以及註冊WebBackForwardList和WebHistoryItem類的本地方法
f) 初始化webicondatabase[register_android_webkit_webicondatabase]
註冊WebIconDatabase類的本地方法
g) 初始化websettings[register_android_webkit_websettings]
初始化gFieldIds靜態變量,以及註冊WebSettings類的本地方法
h) 初始化webview[register_android_webkit_webview]
初始化gWebViewNativeField靜態變量,以及註冊WebView類的本地方法
第二步是WebCoreThread初始化,該初始化只在第一次建立WebViewCore對象時完成,當用戶代碼第一次生成WebView對象,會在初始化WebViewCore類時建立WebCoreThread線程,該線程負責處理WebCore初始化事件。此時WebViewCore構造函數會被阻塞,直到一個WebView初始化請求完畢時,會在WebCoreThread線程中喚醒。
第三步建立EventStub對象,該對象處理WebView類的事件,當WebCore初始化完成後會向WebView對象發送事件,WebView類的EventStub對象處理該事件,而且完成後續初始化工做。
第四步獲取WebIconDatabase對象實例。
第五步向WebViewCore發送INITIALIZE事件,而且將this指針做爲消息內容傳遞。WebView類主要負責處理UI相關的事件,而WebViewCore主要負責與WebCore庫交互。在運行時期,UI線程和WebCore數據處理線程是運行在兩個獨立的線程當中。WebCoreThread線程接收到INITIALIZE線程後,會調用消息對象參數的initialize方法,然後喚醒阻塞的WebViewCore Java線程(該線程在WebViewCore的構造函數中被阻塞)。不一樣的WebView對象實例有不一樣的WebViewCore對象實例,所以經過消息的方式可使得UI線程和WebViewCore線程解耦合。WebCoreThread的事件處理函數,處理INITIALIZE消息時,調用的是不一樣WebView中WebViewCore實例的initialize方法。WebViewCore類中的initialize方法中會建立BrowserFrame對象(該對象管理整個WEB窗體,以frame相關事件),而且向WebView對象發送WEBCORE_INITIALIZED_MSG_ID消息。WebView消息處理函數,會根據消息參數1初始化指定的WebViewCore對象,而且更新WebViewCore的Frame緩衝。
初始化過程的序列圖以下圖所示:
客戶代碼中可使用WebView類的loadUrl方法,請求訪問指定的URL網頁數據。WebView對象中保存着WebViewCore的引用,因爲WebView屬於UI線程,而WebViewCore屬於後臺線程,所以WebView對象的loadUrl被調用時,會經過消息的方式將URL信息傳遞給WebViewCore對象,該對象會調用成員變量mBrowserFrame的loadUrl方法,進而調用WebKit庫完成數據的載入。其調用函數序列以下所示:
網絡數據的載入分別由Java層和C層共同完成,Java層完成用戶交互、資源下載等操做,而C層主要完成數據分析(創建DOM樹、分析頁面元素等)操做。因爲UI線程和WebCore線程運行在不一樣的兩個線程中,所以當用戶請求訪問網絡資源時,經過消息的方式向WebViewCore對象發送載入資源請求。在Java層的WebKit模塊中,全部與資源載入相關的操做都是由BrowserFrame類中對應的方法完成,這些方法是本地方法,會直接調用WebCore庫的C層函數完成數據載入請求,以及資源分析等操做。如上圖所示,C層的FrameLoader類是瀏覽框架的資源載入器,該類負責檢查訪問策略以及向Java層發送下載資源請求等功能。在FrameLoader中,當用戶請求網絡資源時,通過一系列的策略檢查後會調用FrameBridge的startLoadingResource方法,該方法會回調BrowserFrame(Java)類的startLoadingResource方法,完成網絡數據的下載,然後BrowserFrame(Java)類的startLoadingResource方法會返回一個LoadListener的對象,FrameLoader會刪除原有的FrameLoader對象,將LoadListener對象封裝成ResourceLoadHandler對象,而且將其設置爲新的FrameLoader。到此完成了一次資源訪問請求,接下來的任務便是WebCore庫會根據資源數據進行分析和構建DOM,以及相關的數據結構。
本地數據是以data://開頭的URL表示,載入過程和網絡數據同樣,只不過在執行FrameLoader類的executeLoad方法時,會根據URL的SCHEME類型區分,調用DataLoader的requestUrl方法(參看3.1.2.1節對載入器的分析),而不是調用handleHTTPLoad創建實際的網絡通訊鏈接。
文件數據是以file://開頭的URL,載入的基本流程與網絡數據載入流程基本一致,不一樣的是在運行FrameLoader類的executeLoad方法時,根據SCHEME類型,調用FileLoader的requestUrl方法,完成數據加載(參看3.1.2.1節對載入器的分析)。
當用戶拖動滾動條、有窗口遮蓋、或者有頁面事件觸發都會向WebViewCore(Java層)對象發送背景重繪消息,該消息會引發網頁數據的繪製操做。WebKit的數據繪製可能出於效率上的考慮,沒有經過Java層,而是直接在C層使用SGL庫完成。與Java層圖形繪製相關的Java對象有以下幾個:
Picture類
該類對SGL封裝,其中變量mNativePicture其實是保存着SkPicture對象的指針。WebViewCore中定義了兩個Picture對象,看成雙緩衝處理,在調用webKitDraw方法時,會交換兩個緩衝區,加速刷新速度。
WebView類
該類接受用戶交互相關的操做,當有滾屏、窗口遮蓋、用戶點擊頁面按鈕等相關操做時,WebView對象會與之相關的WebViewCore對象發送VIEW_SIZE_CHANGED消息。當WebViewCore對象接收到該消息後,將構建時創建的mContentPictureB刷新到屏幕上,而後將mContentPictureA與之交換。
WebViewCore類
該類封裝了WebKit C層代碼,爲視圖類提供對WebKit的操做接口,全部對WebKit庫的用戶請求均由該類處理,而且該類還爲視圖類提供了兩個Picture對象,用於圖形數據刷新。
下面以Web頁面被鼠標拖拽的狀況爲例子,分析網頁數據刷新過程。當用戶使用手指點擊觸摸屏,而且移動手指,則會引起touch事件的產生,Android平臺會將touch事件傳遞給最前端的視圖相應(dispatchTouchEvent方法處理)。在WebView類中定義了5種touch模式,在手指拖動Web頁面的狀況下,會觸發mMotionDragMode,而且會調用View類的scrollBy方法,觸發滾屏事件以及使視圖無效(重繪,會調用View的onDraw方法)。WebView視圖中的滾屏事件由onScrollChanged方法響應,該方法向WebViewCore對象發送SET_VISIBLE_RECT事件。
WebViewCore對象接收到SET_VISIBLE_RECT事件後,將消息參數中保存的新視圖的矩形區域大小傳遞給nativeSetVisibleRect方法,通知WebCoreViewImpl對象(C層)視圖矩形變動(WebCoreViewImpl::setVisibleRect方法)。在setVisibleRect方法中,會經過虛擬機調用WebViewCore的contentInvalidate方法,該方法會引起webkitDraw方法的調用(經過WEBKIT_DRAW消息)。在webkitDraw方法裏,首先會將mContentPictureB對象傳遞給本地方法nativeDraw繪製,然後將mContentPictureB的內容與mContentPictureA的內容對調。在這裏mContentPictureA緩衝區是供給WebViewCore的draw方法使用,若是用戶選擇某個控件,繪製焦點框時候WebViewCore對象的draw方法會調用,繪製的內容保存在mContentPictureA中,以後會經過Canvas對象(Java層)的drawPicture方法將其繪製到屏幕上,而mContentPictureB緩衝區是用於built操做的,nativeDraw方法中首先會將傳遞的mContentPictureB對象數據重置,然後在從新構建的mContentPictureB畫布上,將層上相關的元素繪製到該畫布上。上面提到,以後會將mContentPictureB和mContentPictureA的內容對調,這樣一次重繪事件產生時(會調用WebView.onDraw方法)會將mContentPictureA的數據使用Canvas類的drawPicture繪製到屏幕上。當webkitDraw方法將mContentPictureA與mContentPictureB指針對調後,會向WebView對象發送NEW_PICTURE_MSG_ID消息,該消息會引起WebViewCore的VIEW_SIZE_CHANGED消息的產生,而且會使當前視圖無效產生重繪事件(invalidate()),引起onDraw方法的調用,完成一次網頁數據的繪製過程。