在 Android 插件化技術(shù)日新月異的今天,,開發(fā)并落地一款插件化框架到底是簡單還是困難,,這個(gè)問題不同人會有不同的答案。但是我相信,,完成一個(gè)插件化框架的 demo 并不是多難的事,,但是要開發(fā)一款完善的插件化框架卻不是一件容易的事,尤其在國內(nèi),,各大 Rom 廠商都對 Android 系統(tǒng)做了一定程度的定制,,這進(jìn)一步加劇了 Android 本身的碎片化問題。 我們在 2016 年開始研究這方面的技術(shù),,經(jīng)過半年的開發(fā),、測試、適配和線上驗(yàn)證,,目前推出了一款比較完善的插件化框架:VirtualAPK,。 之所以現(xiàn)在推出來,是因?yàn)?VirtualAPK 在我們內(nèi)部已經(jīng)得到了很好的驗(yàn)證,,我們在迭代過程中不斷地做機(jī)型適配和細(xì)節(jié)特性的支持,,目前已經(jīng)達(dá)到一個(gè)非常穩(wěn)定的狀況,足以支撐滴滴部分乃至全部業(yè)務(wù)的動態(tài)發(fā)版需求,。目前 VirtualAPK 應(yīng)用于滴滴乘客端和優(yōu)步中國 APP 中,,大家可以去體驗(yàn)。 為了更好地體現(xiàn)出 VirtualAPK 的價(jià)值,,我們決定將其開源,,請猛擊 https://github.com/didi/VirtualAPK 。 VirtualAPK 也是滴滴公司的首個(gè)對外開源項(xiàng)目,,歡迎大家 star,、發(fā)送 pull request,也歡迎大家來使用 VirtualAPK,,我們會給予一定的技術(shù)支持,。 在傳統(tǒng)的 APP 發(fā)布過程中,,總是存在著固定的發(fā)版節(jié)奏,,比如兩周或者一個(gè)月更新一次,這固然沒有問題。但考慮一種情況,,如果一個(gè)版本剛發(fā)布出去,,卻發(fā)現(xiàn)存在大量 crash,這個(gè)時(shí)候我們會怎么辦,?大多數(shù)公司都會選擇立刻發(fā)一個(gè)緊急版本,,然后一批人需要手忙腳亂甚至加班來準(zhǔn)備這個(gè)版本,所以緊急版本還是越少越好,。 其實(shí)不僅僅是因?yàn)橹旅?crash 而緊急發(fā)版,,比如一個(gè)早期創(chuàng)業(yè)公司,需要通過迅速的“試錯(cuò)”來嘗試找準(zhǔn)市場的方向,,這個(gè)時(shí)候就需要更加緊湊的發(fā)版方式,,有些時(shí)候甚至想一天發(fā)一次版。在正常的發(fā)版流程中,,這顯然是不現(xiàn)實(shí)的。但是如果這家創(chuàng)業(yè)公司必須要隨時(shí)可以發(fā)版,,否則就可能被競爭對手搶占先機(jī),,這個(gè)時(shí)候該怎么辦呢? 上述的這兩個(gè)問題,,通過 VirtualAPK,,將不再是問題。通過 VirtualAPK 將業(yè)務(wù)模塊插件化,,然后就可以隨時(shí)通過更新插件的方式來發(fā)布新功能,,不管是修復(fù)致命 crash 還是進(jìn)行業(yè)務(wù)“試錯(cuò)”,都是一種很爽快的體驗(yàn),。 VirtualAPK 是滴滴出行自研的一款優(yōu)秀的插件化框架,,主要有如下幾個(gè)特性。
四大組件均不需要在宿主 manifest 中預(yù)注冊,,每個(gè)組件都有完整的生命周期。
如下是 VirtualAPK 和主流的插件化框架之間的對比。 已經(jīng)有那么多優(yōu)秀的開源的插件化框架,,滴滴為什么要重新造一個(gè)輪子呢?
DroidPlugin 側(cè)重于加載第三方獨(dú)立插件,,比如微信,并且插件不能訪問宿主的代碼和資源,。而在滴滴打車中,,其他業(yè)務(wù)模塊均需要宿主提供的訂單、定位,、賬號等數(shù)據(jù),,因此插件不可能和宿主沒有交互。 其實(shí)在大部分產(chǎn)品中,,一個(gè)業(yè)務(wù)模塊實(shí)際上并不能輕而易舉地獨(dú)立出來,,它們往往都會和宿主有交互,在這種情況下,,DroidPlugin 就有點(diǎn)力不從心了,。 基于上述幾點(diǎn),我們只能重新造一個(gè)輪子,,它不但功能全面、兼容性好,,還必須能夠適用于有耦合的業(yè)務(wù)插件,,這就是 VirtualAPK 存在的意義。 在 加載耦合插件 方面,,VirtualAPK 是開源方案的首選,,推薦大家使用。 通俗易懂地說——
抽象地說——
VirtualAPK 對插件沒有額外的約束,,原生的 apk 即可作為插件。插件工程編譯生成 apk 后,,即可通過宿主 App 加載,,每個(gè)插件 apk 被加載后,都會在宿主中創(chuàng)建一個(gè)單獨(dú)的 LoadedPlugin 對象,。如下圖所示,,通過這些 LoadedPlugin 對象,VirtualAPK 就可以管理插件并賦予插件新的意義,,使其可以像手機(jī)中安裝過的 App 一樣運(yùn)行,。 第一步: 初始化插件引擎 @Overrideprotected void attachBaseContext(Context base) { super.attachBaseContext(base); PluginManager.getInstance(base).init();} 第二步:加載插件 public class PluginManager { public void loadPlugin(File apk);} 當(dāng)插件入口被調(diào)用后,插件的后續(xù)邏輯均不需要宿主干預(yù),,均走原生的 Android 流程,。 比如,在插件內(nèi)部,,如下代碼將正確執(zhí)行: @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_book_manager); LinearLayout holder = (LinearLayout)findViewById(R.id.holder); TextView imei = (TextView)findViewById(R.id.imei); imei.setText(IDUtil.getUUID(this)); // bind service in plugin Intent service = new Intent(this, BookManagerService.class); bindService(service, mConnection, Context.BIND_AUTO_CREATE); // start activity in plugin Intent intent = new Intent(this, TCPClientActivity.class); startActivity(intent);}
如下是 VirtualAPK 的整體架構(gòu)圖,更詳細(xì)的內(nèi)容請大家閱讀源碼和 wiki,。 |
|