Android Chromium WebView學習啟動篇,chromiumwebview
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標準之後。
為什麼要實現跨平台開發?
這是因為在現代越來越高效運轉的社會中,時間就是金錢。具體到軟體開發來說,主要就是開發時間成本。拿現在的行動裝置 App開發來說,我們一般會同時開發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的智能指標技術、線程通訊模型和進程通訊模型,然後再配合使用情景來,逐漸地分析複雜的技術。例如網頁資源下載、網頁分層、分塊、繪製、合成和硬體加速渲染等技術等。
這將會是一個充滿挑戰的學習過程,但是如果能夠堅持下來,收穫也是巨大的,因為我們所學習的知識很有可能就是下一個技術風口!