作者丨Dotry
https://www.jianshu.com/p/57cccc680bb6
在今年的Google I/O大會上,Google向 Android 引入了新 App 動態化框架(即Android App Bundle,縮寫為AAB),AAB是藉助Split Apk完成動態加載,使用AAB動態下發方式,可以大幅度減少應用體積。現在只須在 Android Studio 中構建一個應用 (app bundle),就可以將應用所需的全部內容 (適用於所有設備) 都涵蓋在內:所有語言、所有設備屏幕大小、所有硬體架構。它本身並不支持動態化,只是動態化的一個載體文件,真正實現邏輯並不是它。
1.Split APKs:
多apk 支持以下類型屏幕密度ABI,使用新的拆分機制,構建同一個應用程式的hdpi版本和mdpi版本,能夠共享很多的任務 (如 javac,dx,proguard)。此外,它會被認為是一個單一的variant,並且同一個測試程序將會被用來測試每個多APK。
2.Dynamic Feature Module:
這個概念感覺像是遊戲裡面到某個新地圖才開始下載那樣,不是一來就把所有資源都下載下來。這樣顯得apk更小了,而且就像遊戲邏輯一樣,高級副本的地圖新手沒機會進入,就不必要下載這部分內容,有的用戶可能很久都不會用到部分功能,就可以放在dynamic feature module,等要用的時候再下載。
下面是Dynamic Delivery示意效果圖:
(左) 舊版 APK 交付樣例 - 將全部資源都交付至設備;
(右) 動態交付樣例 - 只向設備交付必要資源
具體一下說明和視頻演示可以查看網站
https://developer.android.com/guide/app-bundle
好處:
Size更小【個人理解是相對用戶來感知來說更小】
Google has claimed that it can reduce app sizes up to 50 percent
Its own apps like YouTube and other apps like LinkedIn which saw a 23% file reduction
安裝更快【base.apk被優化相對來說安裝會更快】
支持動態發布
限制
僅限於通過 Google Play 發布的應用,(Google進一步鞏固自身生態)
需要加入到 Google 的 beta program
最低支持版本Android 5.0 (API level 21)
低於Android 5.0 (API level 21) 的版本GooglePlay會優化Size,但不支持動態交付。
成本
需要升級到Android Studio 3.2修改工程以便支持App Bundle格式
集成Play Core Library
結合Google Play Dynamic Delivery (動態交付) , 實現動態功能
Android App Bundle 支持模塊化,通過Dynamic Delivery with split APKs,將一個apk拆分成多個apk,按需加載(包括加載C/C++ libraries),這樣開發者可以隨時按需交付功能,而不是僅限在安裝過程中。
Base Apk
首次安裝的apk,公共代碼和資源,所以其他的模塊都基於Base Apk
Configuration APKs
native libraries 和適配當前手機屏幕解析度的資源
Dynamic feature APKs
不需要在首次安裝就加載的模塊
具體的結構如下:
具體使用時,在Android Studio新增一項module——Dynamic Feature Module。
選中Dynamic Feature Module直接next到以下頁面
• Enable on-demand: 是否支持按需下載模式。如果不支持,那麼該feature則在安裝app時被安裝。
• Fusing: 如果app運行在Android 5.0(不包括5.0)以下,勾選Fusing則表示該feature會被一起打包至完整apk中。
• Module Title當確認用戶是否想要下載模塊時,平臺使用該標題來向用戶標識模塊。
新建項目生成的項目結構圖如下:
如圖feature生成的目錄結構和我們常用的module結構相差無幾。
例如谷歌官方提供的demo項目結構如下:
在demo中有四個feature,通過module名很清楚這些feature是舉例介紹如何訪問代碼、資源、so等。
我們可以看到源碼裡面主要是通過一個SplitInstallManager類來進行管理不同的模塊的。
以下是加載對應模塊的簡單使用:
dynamic feature module編譯所使用的插件com.android.dynamic-feature通過編譯產物分析,運行示例後,發現在所有dynamic feature模塊build目錄下均會生成apk文件。
直接運行後我們在feature 下打開目錄查看如下:
可以發現會生成一個apk 文件,這個apk文件就是用來被base.apk 調用的。
接著反編譯base.apk,會發現兩個的現象:
• 所有dynamic feature module的代碼、資源、so並未打包至主apk中。
• 主apk manifest信息包括所有dynamic feature module的manifest,即feature manifest會被合併至主apk manifest中。
以上兩個現象需要我們在模塊劃分的時候做好規劃,隨著需求不斷迭代,結構規劃可能需要做對應的調整。
• Build Bundle(s)
Android App Bundle:提供一種全新編譯產物格式文件aab,使用Android Studio提供的App Bundle即可。
生成方式如下:
1.通過命令行生成,在命令行裡輸入以下命令即可:
./gradlew :base:bundleDebug
2.通過Android Studio 生成
點擊「Build Bundle(s)」之後我們會在主工程build目錄下回生成bundle.aab文件,該文件是壓縮格式文件,解壓該aab文件內容如下:
由此可以看到其結構同項目結構分包相似。
打開其中具體某一目錄可以發現其和正常apk解壓後的結構相差無幾:
從aab文件內容,可知其包含base和feature的代碼、資源、so等,同時還有BundleConfig.pb這一配置文件,該配置文件是google play用於拆分apk。如果我們需要在google play上支持動態發布,只需要上傳aab文件即可,後續工作交給google play完成。
使用bundletool測試Android應用程式包在本地使用 bundletool命令行工具:
從GitHub下載bundletool 工具
https://github.com/google/bundletool/releases
執行java –jar bundletool.jar 可以將」.aad」文件轉換成」apks」文件。
例如上述生成一個bundle.aab 文件,採用命令生成bundle.apks文件
java -jar bundletool.jar build-apks --bundle=bundle.aab --output=bundle.apks --ks=features.jks --ks-pass=pass:tcl123 --ks-key-alias=key0 --key-pass=pass:tcl123
執行安裝命令:
java -jar bundletool.jar install-apks --apks=bundle.apks
【目前windows 10 好像是有bug】
有關於命令參數的配置可以見下表:
獲取連結設備信息,命令如下::
java -jar bundletool.jar get-device-spec --output=tcl.json --adb=D:/Android/SDK/platform-tools/adb.exe
我們分割出該apks文件之後就會生成以下apk。命令如下:
java -jar bundletool.jar extract-apks --apks=bundle.apks --output-dir=D:undleapks --device-spec=tcl.json
由此也可以證明我們的生成.aad 文件是正確的。
推薦↓↓↓
涵蓋:程式設計師大咖、源碼共讀、程式設計師共讀、數據結構與算法、黑客技術和網絡安全、大數據科技、編程前端、Java、Python、Web編程開發、Android、iOS開發、Linux、資料庫研發、幽默程式設計師等。