如需轉載,請註明出處!
WebSite: http://www.jjos.org/
作者: 薑江 linuxemacs@gmail.com
QQ: 457283
這是一篇自己寫於一年前的工作文檔,分享出來。
一、WebKit簡介
WebKit是一個開源的瀏覽器網頁排版引擎,包含WebCore排版引擎和JSCore引擎。
WebCore和JSCore引擎來自於KDE項目的KHTML和KJS開源項目。Android平台的Web
引擎架構採用了WebKit項目中的WebCore和JSCore部分,上層由Java語言封裝,並且作
為API提供給Android應用開發人員,而底層使用WebKit核心庫(WebCore和JSCore)進行
網頁排版。
二、WebKit目錄結構
Android平台的WebKit模組分成Java和WebKit庫兩個部分,其目錄結構如下表所示:
WebKit模組目錄結構
Java層(根目錄device/java/android/android/webkit)
BrowserFrame.java
BrowserFrame對象是對WebCore庫中的Frame對象的Java層封裝,用於建立WebCore中定義的Frame,以及為該Frame對象提供Java層回調方法。
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模組提供資料存取操作。
三、WebKit模組架構
Android平台的WebKit模組由Java層和WebKit庫兩個部分組成,Java層負責與Android應用程式進行通訊,而WebKit類庫負責實際的網頁排版處理。Java層和C層庫之間通過JNI和Bridge相互調用,如所示:
3.1 Java層架構3.1.1 主要類別關係
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的相應方法會被調用。
3.1.2 主要類的設計3.1.2.1 資料載入器的設計
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層代碼。
3.2 C層架構3.2.1 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對象建立了關係。
3.2.2 主要類別關係
與Java層相關的C層類如下表所示:
類
功能描述
ChromeClientAndroid
該類主要處理WebCore中與Frame裝飾相關的操作。例如設定狀態列、捲軸、Javascript指令碼提示框等。當瀏覽器中有相關事件產生,ChromeClientAndroid類的相應方法會被調用,該類會將相關的UI事件通過Bridge傳遞給Java層,由Java層負責繪製以及使用者互動方面的處理。
EditorClientAndroid
該類負責處理頁面中文本相關的處理,比如文本輸入、取消、IME資料處理、文本黏貼、文本編輯等操作。不過目前該類只對按鍵相關的時間進行了處理,其他動作均未支援。
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方法)。
四、基本操作分析4.1 WebKit模組初始化
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緩衝。
初始化過程的順序圖表如所示:
初始化完成後Java層和C層類圖關係如所示
中淡綠色的類表示Java層,而灰色類表示C層。
4.2 資料載入4.2.1 載入網路資料
客戶代碼中可以使用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,以及相關的資料結構。
4.2.2 載入本機資料
本機資料是以data://開頭的URL表示,載入過程和網路資料一樣,只不過在執行FrameLoader類的executeLoad方法時,會根據URL的SCHEME類型區分,調用DataLoader的requestUrl方法(參看3.1.2.1節對載入器的分析),而不是調用handleHTTPLoad建立實際的網路通訊串連。
4.2.3 載入檔案資料
檔案資料是以file://開頭的URL,載入的基本流程與網路資料載入流程基本一致,不同的是在運行FrameLoader類的executeLoad方法時,根據SCHEME類型,調用FileLoader的requestUrl方法,完成資料載入(參看3.1.2.1節對載入器的分析)。
4.3 重新整理繪製
當使用者拖動捲軸、有視窗遮蓋、或者有頁面事件觸發都會向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方法的調用,完成一次網頁資料的繪製過程。
~~~ END ~~~