版權聲明:本文爲博主原創文章,未經博主允許不得轉載。
本篇文章只是整理了一些流行的開源插件化技術,其中言論純屬開源作者,不代表本人觀點。
完美內置
所有插件支持內置於宿主包中
高度透明
插件編碼、佈局編寫方式與獨立應用開發無異
插件代碼調試與整包開發無異
極致剪裁
對插件分離所有一切能分離的公共代碼、資源
無縫鏈接
通過設定URI,宿主、本地化應用插件、本地化web插件、在線網頁,以及任何自定義的插件之間能夠相互調起與傳遞參數
跨平臺
目前已支持Android、iOS以及html5插件。並且三者之間可以通過同一套javascript接口進行通信。
二、Small Android(支持平臺:Android API 15(4.0.3))
各個插件框架功能對比:
DyLA : Dynamic-load-apk @singwhatiwanna, 百度 DiLA : Direct-Load-apk @melbcat APF : Android-Plugin-Framework @limpoxe ACDD : ACDD @bunnyblue DyAPK : DynamicAPK @TediWang, 攜程 DPG : DroidPlugin @cmzy, 360
功能
\ DyLA DiLA ACDD DyAPK DPG APF Small 加載非獨立插件[1] × x √ √ × √ √ 加載.so插件 × × ! [2] × × × √ Activity生命週期 √ √ √ √ × √ √ Service動態註冊 × × √ × × √ x [3] 資源分包共享[4] × × ! [5] ! [5] × ! [6] √ 公共插件打包共享[7] × × × × × × √ 支持AppCompat[8] × × × × × × √ 支持本地網頁組件 × × × × × × √ 支持聯調插件[9] × x × × × × √
[1] 獨立插件:一個完整的apk包,可以獨立運行。比如從你的程序跑起淘寶、QQ,但這加載起來是要鬧哪樣?
非獨立插件:依賴於宿主,宿主是個殼,插件可使用其資源代碼並分離之以最小化,這纔是業務需要嘛。
-- “所有不能加載非獨立插件的插件化框架都是耍流氓”。[2] ACDD加載.so用了Native方法(libdexopt.so),不是Java層,源碼似乎未共享。
[3] Service更新頻度低,可預先註冊在宿主的manifest中,如果沒有很好的理由說服我,現不支持。
[4] 要實現宿主、各個插件資源可互相訪問,需要對他們的資源進行分段處理以避免衝突。
[5] 這些框架修改aapt源碼、重編、覆蓋SDK Manager下載的aapt,我只想說“殺(wan)雞(de)焉(kai)用(xin)牛(jiu)刀(hao)”。
Small使用gradle-small-plugin,在後期修改二進制文件,實現了PP段分區。[6] 使用public-padding對資源id的TT段進行分區,分開了宿主和插件。但是插件之間無法分段。
[7] 除了宿主提供一些公共資源與代碼外,我們仍需封裝一些業務層面的公共庫,這些庫被其他插件所依賴。
公共插件打包的目的就是可以單獨更新公共庫插件,並且相關插件不需要動到。[8] AppCompat: Android Studio默認添加的主題包,Google主推的Metrial Design包也依賴於此。大勢所趨。
[9] 聯調插件:使用Android Studio調試宿主時,可直接在插件代碼中添加斷點調試。
透明度
\ ACDD DyAPK APF Small 插件Activity代碼無需修改 √ √ √ √ 插件引用外部資源無需修改name × × × √ 插件模塊無需修改build.gradle × x × √
Step 1. Clone Small (下載源碼)
> cd [你要放Small的目錄] > git clone https://github.com/wequick/Small.git
強烈建議使用git命令行,方便更新維護。Windows用戶入口:Git for Windows
後續更新可以使用命令:git pull origin master
Step 2. Import Sample project (導入示例工程)
打開Android Studio,File->New->Import Project... 選擇Sample文件夾,導入。
Sample
示例工程
app
宿主工程
app.*
包含Activity/Fragment的組件
lib.*
公共庫組件
web.*
本地網頁組件
sign
簽名文件
順便說下,這些app.*跟web.*可以從工具欄的按鈕單獨運行。
其中app.home無法單獨運行是因爲它只包含一個Fragment,沒有Launcher Activity。
Step 3. Build libraries (準備基礎庫)
> [./]gradlew buildLib -q (-q是安靜模式,可以讓輸出更好看,也可以不加)
Step 4. Build bundles (打包所有組件)
> [./]gradlew buildBundle -q (-q是安靜模式,可以讓輸出更好看,也可以不加)
Step 5. Import DevSample project (導入開發工程)
打開Android Studio,File->New->Import Project... 選擇DevSample文件夾,導入。
DevSample
開發工程
buildSrc
組件編譯插件,用於打包組件
small
核心庫,用於加載組件
buildSrc在修改後會被自動編譯。
其他步驟同上。除了編譯單個組件的命令有所不同:
> [./]gradlew :app.main:assembleRelease
P.s. gradlew命令支持縮寫,比如
assembleRelease
可以縮寫爲aR
四、實現Android插件化的核心技術:
五、常見問題 FAQ
插件是否一定得內置到APK中,如果一定要內置,那這個框架僅僅是爲了開發工程中解耦?
內置是爲了首次啓動更快,如果不內置也行,可以在啓動頁下載插件。
目前開源的插件開發框架有很多,Small 跟這些框架的區別是什麼,優缺點呢?
把核心代碼量控制在了一個文件(ApkBundleLauncher)500行以內
不修改aapt源碼,實現了資源id PP段的再分配(原理見Dynamic load resources)
通過對aapt生成的二進制文件的後期加工,最大化分離無用的資源,使得插件包最小達到4k左右
支持對本地化網頁進行插件打包,實現跨平臺
dynamic-load-apk使用代理的方式實現Activity生命週期,插件中不能用this,不夠透明;
Direct-Load-apk對dynamic-load-apk進行了改進,支持this。但也是用代理Activity,實現較爲繁瑣;
Android-Plugin-Framework是一個相對完整的框架,但資源分區方案還不夠理想,不支持加載.so插件;
ACDD 使用了osgi,沒有細看。。坑點是資源分區要使用修改aapt源碼再重新編譯的方案;
DynamicAPK 坑點:修改aapt源碼,不支持.so插件;
DroidPlugin支持對完整apk的動態加載,但是沒有關於非獨立插件的加載(資源分區要複雜得多);
這些框架似乎都不支持AppCompat包(但這很重要,材料設計的Design包等都依賴AppCompat);
Small的開發其實是跟隨1、2、3走過來的。從實際場景出發,基於“輕量、透明、極小化、跨平臺”的理念:
百度工程師開發的 Dynamic-load-apk
melbcat開源的 Direct-Load-apk
limpoxe開源的 Android-Plugin-Framework
bunnyblue開源的 ACDD
攜程工程師開發的 DynamicAPK
360工程師開發的 DroidPlugin
頂
0
踩
0