Android新技术------Android App Bundle之bundletool的使用

为应对应用包体积膨胀问题,Google推出Android App Bundle (AAB)格式,通过按需加载资源,实现应用瘦身。AAB可根据设备特性生成特定APK,大幅减少存储空间占用。

背景

随着应用不断演化,功能越来越复杂,且应用针对不同屏幕设备、不同国家语言资源都打包在同一个App,导致应用包不断增大,据统计自2012年以来应用包大小增长5倍。虽然现在手机的存储空间越来越大,但用户照片、视频等媒体文件品质在逐渐提升,导致设备可用空间逐渐紧缩。

为此Google在去年Google I/O大会讲述Android引入新的App动态化框架(即Android App Bundle,缩写为AAB)。利用Split Apk完成动态加载,使用AAB动态下发方式,可显著缩小应用体积,减少对存储空间的占用。

什么是Android APP Bundles

一个Android应用程序包,包括所有程序的编译代码和资源,但推迟APK的生成。该程序包在安装时可以根据用户设备的屏幕分辨率、cpu架构以及语言为其生成特定的apk,而不用将所有的资源文件包含在apk中,有效减少apk的大小。

Android App Bundle是扩展名为.abb的文件
在这里插入图片描述

base/:应用程序的基本模块始终包含在base应用程序包的目录中
res/,lib/和assets/:这些目录与典型APK中的目录相同。
dex/:与APK不同,app bundle 将每个模块的DEX文件存储在这个单独的目录中。
root/:应用程序包的目录可能包含应用程序加载的基于Java的资源 Class.getResource(),这些文件稍后会重新定位到应用基础APK的根目录以及Google Play生成的每个多APK。
resources.pb:描述每个模块中的代码和资源,这在针对不同设备配置优化APK时非常有用。
BundleConfig.pb:提供有关包本身的信息,例如用于构建应用程序包的构建工具的版本。

如何使用Android APP Bundles

环境要求:Android Studio 3.2+
代码配置:
在app中的build.gradle文件中的android闭包中添加如下代码:

android {

    ......

    bundle {
        density {
            // Different APKs are generated for devices with different screen densities; true by default.
            enableSplit true
        }
        abi {
            // Different APKs are generated for devices with different CPU architectures; true by default.
            enableSplit true
        }
        language {
            // This is disabled so that the App Bundle does NOT split the APK for each language.
            // We're gonna use the same APK for all languages.
            enableSplit true
        }
    }
}

将density、abi、language中的enableSplit设置为true,这样在生成apk时就可以通过屏幕分辨率、cpu架构、语言进行拆分。

修改完毕之后,进行同步,现在,您可以构建App Bundle。转到Build> Build Bundle(s)/ APK(s)并选择Build Bundle(s)
在这里插入图片描述
构建之后会在app> build> outputs> bundle> debug中生成.abb文件。

使用bundletool生成apk

得到Android应用程序包后,有两种方法可以生成特定设备的apk:在本地使用 bundletool命令行工具或者上传到Google Play,由于无法使用Google Play,所以使用bundletool进行apk生成。

bundletool,下载地址,下载bundletool-all-0.9.0.jar文件。

常用命令:

  1. 通过应用包生成apk集
    java -jar bundletool-all-0.9.0.jar build-apks 
    --bundle=app.aab 
    --output=app.apks
  1. 通过应用包生成一组带签名的apk集
    java -jar bundletool-all-0.9.0.jar build-apks 
    --bundle=app.aab 
    --output=app.apks 
    --ks=5658.keystore 
    --ks-pass=pass:android 
    --ks-key-alias=androiddebugkey 
    --key-pass=pass:android
  1. 将apk部署到设备上(需要连接设备,根据设备信息自动提取对应资源并安装)
    java -jar bundletool-all-0.9.0.jar install-apks 
    --apks=app.apks
  1. 为已连接的设备生成apk
    java -jar bundletool-all-0.9.0.jar build-apks
    --connected-device 
    --bundle=app.aab 
    --output=my_app.apks
  1. 通过json文件生成对应的apk
  	java -jar bundletool-all-0.9.0.jar build-apks 
    --device-spec=config.json 
    --bundle=app.aab 
    --output=my_app.apks
  1. 获取已连接设备的json配置文件
	java -jar bundletool-all-0.9.0.jar get-device-spec 
    --output=config.json
  1. 从apk集中提取对应设备apk到app文件夹
    java -jar bundletool-all-0.9.0.jar extract-apks 
    --apks=keyhelp.apks  
    --output-dir=app 
    --device-spec=temp.json

json文件格式:

{
    "supportedAbis": ["arm64-v8a", "armeabi-v7a"],
    "supportedLocales": ["en", "fr"],
    "screenDensity": 640,
    "sdkVersion": 27
}

如果应用支持多种语言需要将支持的语言添加到supportedLocales中去。

由程序包生成的apk集内容:
在这里插入图片描述
特定设备的apk集内容:
在这里插入图片描述

优缺点分析

优点: 有效减小apk大小
在这里插入图片描述
缺点:因其生成的apk集的后缀为apks,只能通过bundletool进行apk安装,无法通过adb install 进行安装。

小结

本文主要介绍了bundletool的使用方法,由于未能连接到Google Play,所以没有介绍Android App Bundle中的动态功能apk的发布。

参考资料

https://developer.android.com/guide/app-bundle/#beta_considerations
https://developer.android.com/studio/command-line/bundletool
https://codelabs.developers.google.com/codelabs/your-first-dynamic-app/index.html#0

<think>我们讨论的是如何检测uni-app打包后的AAB(Android App Bundle)是否满足16KB内存页面对齐要求。这个问题与之前讨论的APK检测类似,但因为AAB是上传到Google Play的格式,检测方法有所不同。 ### 检测AAB满足16KB内存对齐要求的方法 #### 方法1:使用`bundletool`检查本地AAB文件 1. **下载bundletool**:从GitHub下载最新版[bundletool](https://github.com/google/bundletool/releases) 2. **生成APK Set**: ```bash bundletool build-apks --bundle=your_app.aab --output=output.apks ``` 3. **解压APK Set**: ```bash unzip output.apks -d apks_output ``` 4. **检查各APK**: - 进入解压目录,找到对应设备配置的APK(通常位于`splits`或`standalones`目录) - 使用`aapt2`检查: ```bash aapt2 dump badging <apk路径> | grep page-size ``` - 预期输出:`native-code: 'arm64-v8a' (page-size=16384)` #### 方法2:使用Google Play控制台验证 1. 上传AAB到Google Play内部测试轨道 2. 在**发布前检查报告**中查看: - 进入**测试** → **内部测试** → **发布前测试报告** - 检查**设备兼容性**部分,确认无"16KB page size"警告 #### 方法3:本地模拟安装检查 1. 生成设备特定APK: ```bash bundletool extract-apks --apks=output.apks --device-spec=device.json --output-dir=device_apks ``` (需创建`device.json`定义设备参数) 2. 安装到测试设备: ```bash adb install-multiple base-master.apk base-arm64_v8a.apk ``` 3. 运行时验证: - 使用Android Studio Profiler的**Native Memory**跟踪 - 过滤`memalign`调用,检查分配粒度是否为16384字节 ### 关键验证点 1. **ABI过滤**:确保AAB仅包含`arm64-v8a`架构(或同时包含`armeabi-v7a`时,两者都需16KB对齐) 2. **分库对齐**:检查每个动态库(.so文件)的对齐: ```bash # 解压APK后检查.so文件 readelf -l libnative-lib.so | grep -A1 LOAD ``` - 查看`Align`字段值应为`0x4000`(16384的十六进制) ### 配置保障(预防措施) 在`manifest.json`中强制设置: ```json { "app-plus": { "android": { "packagingOptions": { "jniLibs": { "pageSize": 16384 } }, "abiFilters": ["arm64-v8a"] // 关键:仅保留64位架构 } } } ``` > **技术说明**:AAB格式本身不包含最终APK,需通过`bundletool`生成设备专属APK后才能验证页面对齐[^1]。Google Play会为不同设备生成最优APK,因此必须确保所有架构均满足16KB对齐。 §§相关问题§§ 1. 如何验证Google Play实际分发的APK满足16KB内存对齐? 2. 在uni-app中同时支持32位和64位设备时如何配置内存对齐? 3. 使用`bundletool`时出现`INSTALL_FAILED_NO_MATCHING_ABIS`错误如何解决? </think>我将为您详细解释检测uni-app打包后的AAB(Android App Bundle)是否满足16KB内存对齐要求的方法,并提供完整的操作流程: ### 检测AAB满足16KB内存对齐要求的完整方法 #### 方法1:使用bundletool检查(推荐) 1. **安装bundletool**: ```bash # 下载最新版bundletool curl -L0 https://github.com/google/bundletool/releases/download/1.15.6/bundletool-all-1.15.6.jar --output bundletool.jar ``` 2. **生成APK Set并检查**: ```bash # 从AAB生成APK Set java -jar bundletool.jar build-apks --bundle=your_app.aab --output=output.apks # 解压APK Set unzip output.apks -d apks_folder # 检查主模块对齐状态 aapt dump badging apks_folder/splits/base-master.apk | grep page-size ``` 期望输出:`native-code: 'arm64-v8a' (page-size=16384)` #### 方法2:直接检查AAB内容 ```bash # 解压AAB文件(本质是zip) unzip your_app.aab -d aab_unpacked # 检查原生库配置 cat aab_unpacked/BUNDLE-METADATA/com.android.tools.build.libraries/dependencies.pb | grep pageSize # 检查各ABI分库 find aab_unpacked/modules -name "*.so" -exec readelf -l {} \; | grep -A1 LOAD ``` 期望结果: - 所有.so文件的`Align`字段为`0x4000`(16384的十六进制) - 配置文件中显示`pageSize: 16384` #### 方法3:Android Studio验证 1. 打开`build.gradle`确保配置: ```gradle android { bundle { abi { enableSplit true } } packagingOptions { jniLibs { useLegacyPackaging false // 必须关闭 pageSize = 16384 // 关键配置 } } } ``` 2. 使用Analyze APK功能: - 打开Android Studio → Build → Analyze APK - 选择AAB文件 → 查看`BUNDLE-METADATA/com.android.tools.build.libraries` - 验证`pageSize`值为16384 ### 关键验证指标 1. **ABI分库状态**: - 必须有独立的`arm64-v8a`分库 - 检查命令:`aapt dump badging base-arm64_v8a.apk | grep page-size` 2. **文件对齐验证**: ```bash # 检查具体库文件对齐 readelf -l libapp.so | grep -A1 LOAD ``` 输出应包含: ``` LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**14 filesz 0x0004e000 memsz 0x0004e000 flags r-x ``` (`align 2**14`表示16384字节对齐) ### 配置保障(预防性措施) 在`manifest.json`中确保: ```json { "app-plus": { "android": { "packagingOptions": { "jniLibs": { "pageSize": 16384 // 强制16KB对齐 } }, "abiFilters": ["arm64-v8a"] // 关键:只包含64位架构 } } } ``` > **技术说明**:AAB格式要求比APK更严格,必须确保每个模块都包含正确的分库配置。当`.so`文件按16384字节对齐时,系统可优化内存页表(Page Table)管理,减少TLB缺失率[^1]。
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值