漫談Android組件化及Web化


內容來源:2018 年 04 月 14 日,高級Android工程師陳家偉在「2018互聯網開發者大會」進行《漫談Android組件化及Web化》演講分享。IT 大咖說(微信id:itdakashuo)做爲獨家視頻合做方,經主辦方和講者審閱受權發佈。web

閱讀字數:3326 | 9分鐘閱讀微信

嘉賓演講視頻及PPT:t.cn/Rr62oSm網絡

摘要

本次分享主要講述Android組件化和Android web化的原理與實踐。框架

Android動態化介紹

動態化演進

安卓的動態化主要包含三個部分,分別是組件化、插件化、模塊化。模塊化很容易理解,指的是爲了解耦將某一個功能拆分紅獨立的模塊,最多見的模塊有網絡模塊和下載模塊。插件化和組件化的概念就比較模糊,不一樣的框架所作的定義都不同,它們之間的邊界也不太明顯。ide

上圖是某App對插件化和組件化的理解圖示,左面表示的是組件化,右邊表示的是插件化。組件化的機器人是由多個組件構成,插件化的機器人是一個總體能夠進行分發。模塊化

這張示意圖乍看沒什麼問題,可是其實仍是存在漏洞,好比當組件化的機器人某一部分變的足夠大的時候,該部分其實能夠脫離出來成爲新的機器人,而當插件化機器人功能愈來愈弱小的時候也能夠演變從一個組件。總的來講組件化和插件化的邊界並非很明顯,只是根據站的角度和處理問題的方法不一樣而產生的概念性上的定義。工具

Android動態化須要解決的問題

Android動態化須要解決4個問題,分別是Dex加載、資源加載、SO加載、四大組件加載。下文將介紹這四個問題所涉及的安卓的具體部分。組件化

Dex是安卓編譯後的產物,Java會被編譯成class,安卓則對這些class文件進行壓縮處理獲得一個Dex。安卓的資源比較多,有圖片、佈局文件、動畫等。SO是安卓的動態連接庫,通常由C或者C++寫成。安卓的四大組件Activity,Service,Content Provider,BroadcastReceiver必須在AndroidManifest.xml配置文件中聲明纔可以正常加載。佈局

主流動態化框架

目前主流的動態化框架有Atlas、RePlugin、DroidPlugin、VirtualAPK,除開Atlas將本身定義爲組件化框架外,其餘三個都將本身定義爲插件化框架。根據我的的觀察發現,他們主要的區別在於對安卓的四大組件的處理上,Atlas是先定義這些組件再經過打包的方式處理。可是去年Atlas也作了一些插件化的處理,這使得目前的這四個框架都涉及到了插件化。動畫

組件化和插件化

相信你們都常常遇到產品的某些需求要緊急上線的狀況,可是App不一樣於H5開發那樣能夠隨時發版,須要通過衆多的渠道進行發佈,而若是可以作到動態發版,對整個產品的演進和動態開發都會有比較好的推動做用。

另外減小包體積一樣也很重要,通常同個App,iOS的包體積會比Android的更大,這是因爲iOS沒法進行本地代碼的動態下發,而國內的安卓渠道審覈相對比較鬆一些。還有一個須要關注的是熱修復,它可讓咱們即時的修復線上的BUG。

上文提到的這三點其實就是組件化和插件化共同目的,只不過他們在實現手段上有所不一樣。通常組件是和主工程一塊兒打包,插件則能夠獨立打包、另外組件須要藉助打包完成更多工做

動態加載原理

動態加載App思路之類加載

前面提到過插件化要解決的其中一個問題就是Dex加載。在Java中能夠經過ClassLoader加載class文件,安卓方面則提供了BaseDexClassLoader。BaseDexClassLoader內部有不少DexFile,它是Dex的文件描述,要想實現類加載,能夠直接將插件的DexFile前插到BaseDexClassLoader。這種方式就是單類加載器。

安卓中系統類由BootClassLoader加載,PathClassLoader繼承自BootClassLoader,加載的是App類。Altlas爲了實現類加載,將PathClassLoader替換爲了本身的ClassLoader——DelegateClassLoader,這時全部類的加載都會通過DelegateClassLoader,且每一個插件都由獨立的PluginClassLoader加載,這些類的查找則由DelegateClassLoader完成。這種方式是多類加載器。

動態加載App思路之資源加載

安卓在打包的時候會爲每一個資源分配一個32位Int型的ID,採用16進製表示。0x後面是相似PPTTEEEE的形式,TT表明類別,EEEE表明條目,安卓中全部打包資源ID的PP都是7F。

安卓中的資源加載有兩種方式,第一種是資源隔離。指的是每一個插件由不一樣的Resources對象加載資源(安卓中經過Resources對象獲取資源),這是爲了不因爲資源ID相同形成的資源衝突問題。

第二個資源加載方式是資源分區,它經過修改安卓的打包工具,使得能夠變動資源ID的PP,已達到避免ID重複的目的。

對比這兩種方式能夠發現,資源隔離的好處在於不須要修改打包工具, 畢竟打包工具是使用C++寫的,維護起來也比較麻煩(aapt2已經支持資源分區)。資源分區的優點在於可以資源共用,由於它能夠共用一個Resources對象,同時還能夠避免資源衝突。

動態加載App之四大組件加載

四大組件的加載一樣有兩種方式。一種是經過合併manifest信息方式,好比手動拷貝或者打包,將插件Menifest信息合併入主APP。另外一種是事先聲明空的四大組件,再經過Hock掉系統的入口來啓動四大組件。

Google玩轉動態化

雖然動態框架在國內很流行,但國外對此卻不是很熱衷,他們更多的仍是使用React Native。

國內的動態框架主要是研究如何經過反射調用或者Hock掉系統API來達到目的,不過系統API的調用其實存在着風險,由於每一個版本的私有API的變更都是挺大的。爲此Google也提供了一種動態框架——Instant,它經過Google Play Service加載,即有插件化也有組件化的特色,經過aapt2來完成資源分區,對於四大組件的加載採用預埋、代理的方式啓動Activity service。

Web化介紹

通常App的活動頁都是使用H5開發,由於H5能夠進行動態更新。可是H5體驗上仍是不如Native,在動畫以及一些高級功能方面也不夠強。

而組件化也存在着問題,在最新發布的Android P版本中限制了對私有API的訪問,一旦訪問私有API 應用就會崩潰。雖然能夠經過某些技術手段攻克這一限制,可是其實還有另外一種方式——SPA(單頁面應用)。 對於Web端的SPA,它只有一個HTML文件,而後經過JS渲染,以達到在一個HTML的進行頁面跳轉的目的。

下面來看下Android中的web化。

首先是React Native。React Native中每一個頁面都是一個View,且都在Activity中,它經過控制View的切換來進行頁面跳轉。

Android提供了一種佈局容器——Fragment,Activity能夠承載不少Fragment,經過切換Fragment也能夠達到頁面切換的效果。這就是Android Native的web化。

Android web核心原理

Android Native web實現的核心是多類加載器、資源隔離以及context替換。

由於要保證命名和混淆規則不能出現同一個類名,因此沒法使用單類加載器。多類加載器因爲採用不一樣ClassLoader加載插件,所以不用顧慮命名是否重複。

Context替換指的是將Fragment中的Context替換成咱們自定義的Context。Fragment中全部的類和資源都是經過Context訪問,而經過自定義Context就能達到動態加載Activity外部插件的目的。

相關文章
相關標籤/搜索