Android:關於AAB的知識點整理


2018年,google推出了aab技術。在此之后google發布通知:從 2021 年 8 月起,新應用需要使用 Android App Bundle 才能在 Google Play 中發布。

這意味着以GP為主要平台的海外版本,都需要使用aab。那么什么是aab,和apk有什么不同呢?

aab官方介紹:https://developer.android.com/guide/app-bundle

簡單地說aab就是一個帶有很多分包數據的壓縮包。它將一個apk拆分了多個小包,比如按CPU架構拆分,按語言拆分等等,最終移動設備安裝時只需要下載需要的分包即可。

apk可以直接安裝到用戶的設備上,但是aab只是一種發布格式,所以不能直接安裝。但是可以使用bundletool命令行連接設備進行模擬安裝。

技術細節

aab的數據格式

上面提到,aab其實是一個壓縮包,它包含了一系列的文件。下圖顯示了一個aab文件內部的組成:

aab
│ BundleConfig.pb
├─base
│ │ assets.pb
│ │ native.pb
│ │ resources.pb
│ ├─assets
│ ├─dex
│ │ classes.dex
│ ├─lib
│ │ └─armeabi-v7a
│ │ libmain.so
│ │ libmonobdwgc-2.0.so
│ │ libMonoPosixHelper.so
│ │ libunity.so
│ ├─manifest
│ │ AndroidManifest.xml
│ └─res
├─BUNDLE-METADATA
│ └─com.android.tools.build.libraries
│ dependencies.pb
└─META-INF
ANDROIDD.RSA
ANDROIDD.SF
MANIFEST.MF

                                                                                                                                                                                                      

aab存在的目的是為了拆分出一系列的apk文件。為了能夠拆分出來,首先就需要收集數據文件,並對數據文件進行整理,標記每個文件的作用。另外還需要配置拆分的規則。

其中所有的pb文件,其數據結構都可以在以下地址找到:

https://github.com/google/bundletool/blob/master/src/main/proto

base目錄

在base目錄下,我們會發現很多文件和apk大部分是相同的,但是用途又有點不同。

數據文件

  • manifest.xml:它和apk中的一樣,都是一些配置項。但不同的是,apk中這個文件是二進制的格式,而aab中用的是pb格式。
  • res目錄/assets目錄/libs目錄/dex目錄:和apk是相同的組織形式,唯一的區別是res目錄下的配置文件,全部也是用的pb格式

標記數據

  • assets.pb
  • native.pb
  • resources.pb

assets.pb,native.pb,resources.pb是base中核心的內容,它列舉了整個base下所有文件的組成信息,比如某個文件用於某個ScreenDensity(HDPI,XHDPI,XXHDPI之類),或者某個so文件用於某個CPU架構等等。有了這些數據,在拆分apk的時候,就可以將不同的文件拆分到不同的apk中。

BundleConfig.pb

buildconfig用於配置拆分的規則,見https://github.com/google/bundletool/blob/master/src/main/proto/config.protoh

其中也包含了很多的優化項,部分采用gradle進行打包aab的時候會影響到buildconfig的數據,比如UncompressNativeLibraries

https://developer.android.com/studio/releases/gradle-plugin#4-0-0-issues

構建 Android App Bundle 時,由以 Android 6.0(API 級別 23)或更高版本為目標平台的 App Bundle 生成的 APK 現在默認包含原生庫的未壓縮版本。這項優化無需設備創建庫的副本,因此減少了應用占用的存儲空間。如果您想要停用此優化,請在 gradle.properties 文件中添加以下代碼:

android.bundle.enableUncompressedNativeLibs = false

另一個在gradle工程里面影響拆分配置是的build.gradle文件下的bundle模塊,如(unity2018默認生成)

bundle {

    language {

        enableSplit = false

    }

    density {

       enableSplit = false

    }

    abi {

       enableSplit = true

    }

}                                                                                                                                                                                               

這會影響最終的拆包,不會做語言的拆分和density的拆分。如果在unity中含有多國語言或者多個ScreenDensity,那么可以在PlayerSetting的Publishing Setting中勾選Custom Gradle Template,修改這個值

注意:如果使用的是bundltool打包aab,因為沒有gradle相關的文件,所以需要修改buildconfig.json,新增UncompressNativeLibraries=false的配置。見用bundletool打包aab

2、拆分apk:aab到apks

在android lolopop以上,會有SplitApks的功能。它允許一個應用程序可以分散在多個apk中,但是運行起來仍然是一個程序。因此,aab利用這一機制,將aab文件拆分為多個apk,最終根據用戶設備,按需安裝必要的apk即可。

aab一般來說會根據ScreenDensity,CPU架構和本地化語言進行拆分。這樣的會,用戶將不會下載用不到的資源,從而大大減少下載的內容大小。提高下載效率。

clip_image002

在gp平台進行下載安裝,或者使用bundletool安裝apks的時候,過程如下。

平台或者bundletool首先會判斷系統是否支持SplitApk功能,即設備的android版本高於或等於Android Lolipop

如果含有該功能,則根據設備的ScreenDensiny,CPU架構和本地化語言下載對應的分包

clip_image004

通過bundletool,可以將aab轉為一個叫做apks的文件,它也是一個壓縮包

在這個包里面文件結構如下(為了方便刪除了一些本地化語言的apk),可以在splits下發現有很多的分包apk。

而對於Android lolipop之前,則會使用standlones里面的apk

apks
│  toc.pb
├─splits
│      base-af.apk
│      base-am.apk
│      base-ar.apk
│      base-arm64_v8a.apk
│      base-armeabi_v7a.apk
│      base-as.apk
│      base-az.apk
│      base-hdpi.apk
│      base-ldpi.apk
│      base-lo.apk
│      base-lt.apk
│      base-lv.apk
│      base-master.apk
│      base-mdpi.apk
│      base-mk.apk
│      base-tr.apk
│      base-tvdpi.apk
│      base-uk.apk
│      base-ur.apk
│      base-uz.apk
│      base-vi.apk
│      base-xhdpi.apk
│      base-xxhdpi.apk
│      base-xxxhdpi.apk
│      base-zh.apk
│      base-zu.apk|
└─standalones
        standalone-arm64_v8a_hdpi.apk
        standalone-arm64_v8a_ldpi.apk
        standalone-arm64_v8a_mdpi.apk
        standalone-arm64_v8a_tvdpi.apk
        standalone-arm64_v8a_xhdpi.apk
        standalone-arm64_v8a_xxhdpi.apk
        standalone-arm64_v8a_xxxhdpi.apk
        standalone-armeabi_v7a_hdpi.apk
        standalone-armeabi_v7a_ldpi.apk
        standalone-armeabi_v7a_mdpi.apk
        standalone-armeabi_v7a_tvdpi.apk
        standalone-armeabi_v7a_xhdpi.apk
        standalone-armeabi_v7a_xxhdpi.apk
        standalone-armeabi_v7a_xxxhdpi.apk

3、bundltool

上面我們說了很多的bundltool,這里提一下這個工具,Github地址:https://github.com/google/bundletool

可以從releases下載最新的版本

它的作用主要是(其他功能請自行參考github):

  • 打包aab
  • 通過aab轉apks
  • 安裝apks到設備

在這個文章中介紹了bundletool進行打包的內容:https://developer.android.com/studio/build/building-cmdline#bundletool-build

在這個文章中介紹了后2個內容:https://developer.android.com/studio/command-line/bundletool

要注意的是,aab轉apks的時候需要進行簽名,否則將無法安裝

鏈接整理

官方介紹:https://developer.android.com/guide/app-bundle

官方博文:https://medium.com/google-developer-experts/exploring-the-android-app-bundle-ca16846fa3d7

BundleTool:https://github.com/google/bundletool

BundleTool的prop數據格式:https://github.com/google/bundletool/blob/master/src/main/proto

BundleTool打包aab:https://developer.android.com/studio/build/building-cmdline#bundletool-build

BundleTool安裝測試:https://developer.android.com/studio/command-line/bundletool

UncompressNativeLibraries問題:https://developer.android.com/studio/releases/gradle-plugin#4-0-0-issues


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM