Android Chromium WebView學習啟動篇
Android從4.4起提供基于Chromium實現的WebView。此前WebView基于WebKit實現。WebKit提供網頁解析、 布局和繪制以及JS運行等基礎功能。Chromium在WebKit基礎上為WebView提供進程、線程和渲染等基礎構架。因此基于Chromium實 現的WebView更好地提供了網頁瀏覽功能。從本文開始我們啟動對Android Chromium WebView的學習。
老羅的新浪微博: http://weibo.com/shengyangluo ,歡迎關注!
學習WebView并不只是為了研究它是如何在應用程序中嵌入一個瀏覽器來顯示網頁的,而是以WebView作為切入點去研究一個現代化的瀏覽器 是如何實現的。就好比學習Android系統并不只是為了研究它的應用程序是如何運行的,而是以Android系統為切入點去研究一個現代化的移動操作系 統是如何實現的。
為什么要選擇瀏覽器作為下一個研究點?
這是因為瀏覽器是到目前為止,最有機會成為跨平臺開發的一種技術,而且大家對它的接受程度也很高,特別是有HTML5標準之后。
為什么要實現跨平臺開發?
這是因為在現代越來越高效運轉的社會中,時間就是金錢。具體到軟件開發來說,主要就是開發時間成本。拿現在的移動應用開發來說,我們一般會同時開 發Android和iOS兩個版本。它們功能是基本一樣的,但是因為它們使用的開發語言和運行的平臺不一致,導致了要分別對它們進行開發。這樣自然就會提 高開發成本。當然我們可以在某種程度上為Android和iOS兩個版本的應用開發一些基礎庫來盡量降低開發成本。這些基礎庫的核心功能使用C/C++來 開發,然后封裝一套Java接口和一套Objective-C接口分別給Android和iOS使用。然而這并不能徹底地解決跨平臺的問題,例如UI及其 相關的邏輯就很難通過跨平臺的基礎類庫實現。
為什么要選擇Android平臺上基于Chromium實現的WebView作為切入點研究瀏覽器?
這個問題的三個關鍵字是Android、Chromium和WebView。
首先看關鍵字Chromium。如果你沒有聽說過Chromium,也應該會聽說過Chrome瀏覽器。與其它的瀏覽器相比,Chrome瀏覽器 的多進程架構和快速打開網頁的能力相當驚艷,而它就是基于Chromium實現的。Chromium是一個開源的由Google主導的瀏覽器工 程,Chrome瀏覽器會選擇在它的某一個穩定版本進行開發和發布。除了Chrome瀏覽器,Chrome OS也是基于Chromium開發的。由此就可見,Chromium是一個具有深厚技術背景的開源工程,并且它使用的架構是OS級別的,要不然 Chrome OS就不能輕易地基于它來開發。
接下來看關鍵字WebView。Android系統從4.4以及以后版本提供的WebView,與Chrome和Chrome OS一樣,都是基于Chromium實現的。也就是說,WebView、Chrome和Chrome OS都是Chromium的客戶,其中又以WebView提供的瀏覽器功能是最簡單的。因此選擇WebView作為切入點,可以使得我們快速掌握地 Chromium所涉及到的瀏覽器技術。最后看關鍵字Android。
最后看關鍵字Android。Chromium是一個跨平臺的瀏覽器工程,它可以在目前流行的PC和移動平臺上編譯和運行。這同時也意味著它的某 些模塊實現是與平臺相關的,例如渲染相關的模塊實現與具體的平臺有關。Android系統是我們熟悉的,也已經研究過幾年的時間了,因此它是最好的選擇。
學習瀏覽器技術可以得到什么?
瀏覽器要處理的兩個核心對象是HTML和JavaScript。HTML用來實現網頁UI,涉及到的最核心技術是UI渲染技術。JavaScript用來實現網頁功能,涉及到的最核心技術JavaScript引擎技術。
一切帶有屏幕的智能設備,UI都是其所運行系統的一個核心模塊,它負責與用戶進行交互,以及將交互結果反饋給用戶,從而形成一個閉環。用戶在使用 一個系統的時候,最先接觸到的就是它的UI,經常接觸的也是它的UI,因此UI的好壞直接就影響到了系統用戶體驗的好壞。用戶體驗對一個系統來說是至關重 要的,例如,很多人覺得iOS系統比Android系統好用的其中一個原因就是前者的用戶體驗更好。
衡量一個系統的用戶體驗好與壞的其中一個重要標準就是UI的流暢與否,其中又以動畫的流暢與否為核心,因為一個流暢的動畫顯示需要的UI渲染速度 是60fps。為了達到60fps的渲染速度,各個系統在實現UI模塊的時候,可謂是費盡心思、盡其所能。通常都會使用諸如縱向分層、橫向分塊的渲染策 略。
所謂縱向分層,就是在Z軸方向上按層來劃分UI,這樣帶來的好處在渲染UI的每一幀時,不必每一層都進行重繪。這種分層渲染策略使用到了一種稱為 “繪制-合成”的UI渲染技術。也就是各層負責繪制好自己的UI,然后再由一個單獨的模塊對它們進行合成。這樣在渲染UI的每一個幀時,只有UI發生了變 化的層才需要重新進行繪制,沒有發生UI變化的層只需要參與合成這一步即可。這種技術可以大大地減少渲染操作,從而獲得更流暢的UI體驗。
所謂橫向分塊,就是對于UI的每一個層,按照一定的規則對其進行分塊,這樣帶來的好處就是在渲染UI的每一幀遇到一個需要進行重新繪制的層時,不 必對該層的所有內容都進行重新繪制,只需要繪制那些在可視區間的塊即可。這樣也可以在某種程度上減少渲染操作,從而獲得更流暢的UI體驗。
現在的智能設備配備的CPU都是多核的。為了能夠充分地利用CPU多核特性,一幀UI渲染通常分兩步進行:第一步是收集UI繪制命令;第二步是執 行UI繪制命令。每一步都是在一個獨立的線程完成,因此就可以充分地利用CPU的多核特性:在執行第N幀的UI繪制命令的同時,收集第N+1幀的UI繪制 命令。此外,對于第一步收集到的UI繪制命令,還可以做一些額外的優化。當我們收集到一幀UI的所有繪制命令的時候,我們就相當于是知悉了這一幀UI的全 貌。知悉了一個UI幀的全貌之后,就可以進行一些優化,例如對某些UI繪制命令進行重排和合并,以及丟棄那些被遮擋的UI相關的繪制命令。這些優化同樣是 可以減少渲染操作,從而獲得更流暢的UI體驗。
現在的智能設備,很多都配備了GPU,這意味著我們可以使用GPU進一步提高UI的渲染速度,這就是所謂的硬件加速渲染技術。例如對于我們前面提 到的UI層和塊,可以直接以GPU的紋理或者FBO來進行繪制和合成。GPU具有成熟和專業的UI渲染技術,因此通過它來渲染UI,可以獲得更流暢的UI 體驗。
以上提及到的所有UI渲染技術,不管是什么系統,我們都可以或多或少地看到它們的影子,因此它們都是通用的、現代化的UI渲染技術。如果掌握了這 些UI渲染技術,那么不管以后流行的是什么系統,我們都可以輕松應對。因此,學習瀏覽器技術可以得到的第一點核心技術就是現代化的先進UI渲染技術。
不知道同學們有沒有發現,最近幾年時不時都看到有新的編程語言發布,特別是伴隨著新系統的發布,其中比較有名的就是Google的Go語言和 Apple的Swift語言。我們在驚嘆這些編程語言方便好用的同時,有沒有想過它們背后是如何設計和實現的呢?如果有考慮過這個問題的話,我們就不得不 提到JavaScript這個古老而又流行的編程語言。
JavaScript被視為一個“玩具語言”,據說它只花了2個星期設計,然后被使用了20年。在20年的時間里,大家一邊在用它,然后又一邊在 罵它。這足見大家是有多么的喜歡它,正所謂”罵是愛,打是親“嘛。JavaScript雖然天生是為操作網頁而設計的,但是它并不僅僅是應用在網頁前端應 用開發上,它還滲透了移動端和服務端應用開發上。
在移動端上,近兩三年出現了不少專門針對手機的Web OS,例如Firefox OS、Ubuntu Mobile OS、Tizen OS以及阿里的云OS,都支持運行Web應用,這意味在這些系統上可以使用JavaScript來開發應用。當然,在Android和iOS上也可以開發 Web應用,不過它們都是要運行在WebView之上,不是直接在OS層面上得到支持。在服務端上,Node.js就是一個有代表性的框架,它使得我們可 以使用JavaScript來開發Web服務器。
除了在移動端和服務端上,JavaScript甚至還應用在MCU(Microcontroller Unit)領域上,也就是俗稱的單片機領域上。這些MCU提供了一個JavaScript運行環境,從而使得我們可以使用JavaScript操作它們。
一個本來只是設計用在網頁開發的語言,由于它的簡潔和易用性,現在不僅滲透到移動端、服務器端開發上,還滲透到了MCU領域上,這足以看到 JavaScript是如此廣泛地被開發者接受和使用。當然,JavaScript廣泛地被開發者接受和使用,并不意味著它是完美的,例如性能就是一個比 較突出的問題。但是會不會在以后的某一天,當JavaScript的性能問題被解決之后,所有能夠編程的領域,都會被JavaScript代替呢?
不管如何,鑒于現在JavaScript的流行性,作為一個軟件開發從業者,我們不僅會使用JavaScript,還需要知道 JavaScript在背后是如何運行的,這樣才能達到一個更高的境界。JavaScript是一種動態語言,與C/C++、Java這些靜態語言一樣, 在實現上都是涉及到了編譯相關的知識,例如語法解析、生成語法樹、生成字節碼指令、生成本地指令和指令優化等。只不過對于動態語言來說,這些操作發生在應 用程序運行時,只對于靜態語言來說,這些操作發生應用程序運行前。此外,運行JavaScript的引擎與運行Java字節碼的虛擬機一樣,在運行時都提 供了內存自動管理技術,也就是會執行GC。由此可見,學習JavaScript可以獲得很多編譯語言相關的知識。這也是學習瀏覽器技術可以得到的第二點核 心技術。
當我們學習的是基于Chromium的瀏覽器技術的時候,我們就不僅僅是可以獲得上面提到的兩個核心技術,還可以學習到一個復雜系統的架構,例如 它的對象管理技術、多進程架構和多線程編程模型等等。一言蔽之,學習瀏覽器技術可以使我們獲得很多現在和甚至未來都流行的計算機技術。
Android Chromium WebView的學習路線是什么?
我們將通過分析Android 5.0版本源碼自帶的chromium_org工程來學習Android Chromium WebView的實現,并且是使用循序漸進的學習方法,先從一些基礎知識學起,例如Chromium的智能指針技術、線程通信模型和進程通信模型,然后再 配合使用情景來,逐漸地分析復雜的技術。例如網頁資源下載、網頁分層、分塊、繪制、合成和硬件加速渲染等技術等。
這將會是一個充滿挑戰的學習過程,但是如果能夠堅持下來,收獲也是巨大的,因為我們所學習的知識很有可能就是下一個技術風口!