Android App Bundle是一种改进的应用程序打包方式,能大幅度减少应用体积。简而言之,可以理解Google 官方的动态发布方案。按照Google官方的说法:
Android App Bundle 是一种全新的上传格式,其中包含您应用的所有编译好的代码和资源,但 APK 生成及签名工作则交给 Google Play 来处理。它使用全新的应用发布格式(aab)和Google Play的Dynamic Delivery(动态交付)上传您的应用,生成和提供针对每个用户设备进行优化的APK。
(1)减少安装包的大小
来看一下Google官方提供的数据:
(2)定制化分发
(3)应用内更新
可以做到即时、灵活的更新,所有的更新工作都是通过Google Play帮您完成。
Android App Bundle 支持模块化,通过结合Google Play 的Dynamic Delivery (动态交付) ,将一个apk拆分成多个apk,按需加载(包括加载C/C++ libraries),这样开发者可以随时按需交付功能,而不是仅限在安装过程中。
Dynamic feature APKs
不需要在首次安装就加载的模块
下图展示了该应用的各个 APK 的依赖关系树。请注意,基本 APK 构成树的头部,所有其他 APK 都依赖于基本 APK。
注意:无需自己编译这些 APK,Google Play 会根据您通过 Android Studio 编译的单个签名 app bundle 来为您完成编译。
Google Play 的新应用服务模式名叫“Dynamic Delivery”,它会使用您的 app bundle 针对每位用户的设备配置生成并提供经过优化的 APK,因此他们只需下载运行您的应用所需的代码和资源。您无需再编译、签署和管理多个 APK 来支持不同的设备,而用户也可以下载更小、更优化的下载文件包。
App bundle 与 APK 的不同之处在于,您无法将其部署到设备。相反,它是一种上传格式,可将您应用的所有经过编译的代码和资源都包含在一个编译工件中。因此,在您上传已签名的 app bundle 后,Google Play 编译和签署应用 APK 所需的一切就已准备就绪,并将通过 Dynamic Delivery 向用户提供这些 APK。
在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)。
得到Android应用程序包后,有两种方法可以生成特定设备的apk:
通过Google Play Console方式自动生成的过程比较简单。如下图所示在相应位置上传aab文件即可:
下面,我主要介绍一下如何通过bundletool工具,手动生成apk。
使用bundletool生成apk:
(1)通过应用包生成一组的apk集(可根据需要生成相关apk集)
java -jar bundletool-all-0.12.0.jar build-apks
--bundle=app.aab
--output=app.apks
------------为连接的设备------------
--connected-device
--------------带签名--------------
--ks=../../keystore/app.jks
--ks-pass=pass:123456
--ks-key-alias=alias
--key-pass=pass:123456
(2)将apk部署到设备上(需要连接设备,根据设备信息自动提取对应资源并安装)
java -jar bundletool-all-0.12.0.jar install-apks
--apks=app.apks
(3)获取已连接设备的json配置文件
java -jar bundletool-all-0.12.0.jar get-device-spec
--output=config.json
json配置文件内容:
{
"supportedAbis": ["x86"],
"supportedLocales": ["zh-CN", "en-US"],
"deviceFeatures": ["reqGlEsVersion=0x30000", "android.hardware.audio.output", "android.hardware.camera", "android.hardware.camera.any", "android.hardware.faketouch", "android.hardware.fingerprint", "android.hardware.location", "android.hardware.location.gps", "android.hardware.location.network", "android.hardware.microphone", "android.hardware.screen.landscape", "android.hardware.screen.portrait", "android.hardware.sensor.accelerometer", "android.hardware.sensor.ambient_temperature", "android.hardware.sensor.barometer", "android.hardware.sensor.compass", "android.hardware.sensor.gyroscope", "android.hardware.sensor.light", "android.hardware.sensor.proximity", "android.hardware.sensor.relative_humidity", "android.hardware.telephony", "android.hardware.telephony.gsm", "android.hardware.touchscreen", "android.hardware.touchscreen.multitouch", "android.hardware.touchscreen.multitouch.distinct", "android.hardware.touchscreen.multitouch.jazzhand", "android.hardware.usb.accessory", "android.hardware.wifi", "android.software.app_widgets", "android.software.autofill", "android.software.backup", "android.software.connectionservice", "android.software.cts", "android.software.device_admin", "android.software.home_screen", "android.software.input_methods", "android.software.live_wallpaper", "android.software.managed_users", "android.software.midi", "android.software.picture_in_picture", "android.software.print", "android.software.voice_recognizers", "android.software.webview", "com.google.android.apps.dialer.SUPPORTED", "com.google.android.feature.EXCHANGE_6_2", "com.google.android.feature.GOOGLE_BUILD", "com.google.android.feature.GOOGLE_EXPERIENCE"],
"glExtensions": ["GL_EXT_debug_marker", "GL_OES_EGL_image", "GL_OES_EGL_image_external", "GL_OES_depth24", "GL_OES_depth32", "GL_OES_element_index_uint", "GL_OES_texture_float", "GL_OES_texture_float_linear", "GL_OES_compressed_paletted_texture", "GL_OES_compressed_ETC1_RGB8_texture", "GL_OES_depth_texture", "GL_OES_texture_half_float", "GL_OES_texture_half_float_linear", "GL_OES_packed_depth_stencil", "GL_OES_vertex_half_float", "GL_OES_texture_npot", "GL_OES_rgb8_rgba8", "GL_EXT_color_buffer_float", "ANDROID_EMU_CHECKSUM_HELPER_v1", "ANDROID_EMU_native_sync_v2", "ANDROID_EMU_native_sync_v3", "ANDROID_EMU_dma_v1", "GL_OES_EGL_image_external_essl3", "GL_OES_vertex_array_object", "GL_KHR_texture_compression_astc_ldr", "ANDROID_EMU_gles_max_version_3_0"],
"screenDensity": 420,
"sdkVersion": 26
}
补充:当然,也可以通过json配置文件,生成对应的apk集。
java -jar bundletool-all-0.12.0.jar build-apks
--device-spec=config.json
--bundle=app.aab
--output=app.apks
(4)从apk集中提取对应设备apk到app文件夹
java -jar bundletool-all-0.12.0.jar extract-apks
--apks=app.apks
--output-dir=app
--device-spec=config.json
最终在app文件夹下会生成如下apk: