The App Bundle is the new official publishing format that app developers use to publish their apps on Google Play as opposed to APK, the traditional way that was done for over 10 years of android’s history.
Splitting the Publishing from the Serving format
In the past, app developers uploaded monolithic APKs to Google Play, and the channel acted like a dumb pipe that did the distribution to the users.
But with the App Bundle, a conscious decision was made to split the publishing format and the serving format. Developers now put everything in this publishing format, and then Google Play processes it and generates optimised APKs to serve the best possible APK to the end device.
Testing Android App Bundle
This is where the bundletool
comes in. It is actually the underlying tool that Google Play and the Android Gradle plugin use to build .aab
files. This tool is also available as a command-line tool so that developers can test their app locally and emulate Play server-side build and test out Play App Delivery or Asset Delivery flows, before uploading the artefact.
The tool has a few different responsibilities that help developers manipulate Android App Bundles:
- Build an Android App Bundle from pre-compiled modules of a project.
- Generate an APK Set archive containing APKs for all possible devices.
- Extract APK(s) from the APK Set compatible with a given device.
- Install APK(s) from the APK Set compatible with a connected device.
- Extract device spec from a device as a JSON file.
- Add code transparency to an Android App Bundle. Code transparency is an optional code signing mechanism.
- Verify code transparency inside an Android App Bundle, APK files or an application installed on a connected device.
How to build APK sets from App Bundle
The command build-apks
is used to build an APK set for the bundle. It will contain all the APKs for all the modules in the project.
bundletool build-apks
--bundle=/ExampleApp/example_app.aab
--output=/ExampleApp/example_app.apks
If the APKs were installed on a device, they would need to be signed with a private key, all the APKs contained in the APK set will be signed and installable. Note, if signing information is not specified, bundletool
will attempt to sign the APK with a debug key.
bundletool build-apks
--bundle=/ExampleApp/example_app.aab
--output=/ExampleApp/example_app.apks
--ks=/ExampleApp/keystore.jks
--ks-pass=file:/ExampleApp/keystore.pwd
--ks-key-alias=ExampleKeyAlias
--key-pass=file:/ExampleApp/key.pwd
Generating APK sets for devices
You can target a device by specifying its configuration in a JSON file. This file can be created manually with specifying information about supported Application Binary Interfaces (ABIs), Locales, Device Features, OpenGL Implementations, Device Screen Density and the SDK version. Or just simply delegate this work to the useful command of bundletool
, get-device-spec.
{
"supportedAbis": ["arm64-v8a", "armeabi-v7a", "armeabi"],
"supportedLocales": ["en-US", "de-DE", "mk-MK"],
"deviceFeatures": ["android.hardware.bluetooth","android.hardware.camera", "android.hardware.microphone","android.hardware.nfc"...],
"glExtensions": ["GL_OES_EGL_image","GL_OES_EGL_image_external","GL_OES_EGL_sync"...],
"screenDensity": 440,
"sdkVersion": 30
} pixel4a.json
bundletool build-apks
--bundle=/ExampleApp/example_app.aab
--output=/ExampleApp/example_app.apks
--device-spec=pixel4a.json
When passing the flag connected-device
, bundletool
will create APKs just for the device currently connected to, or serial ids can be specified with the command device-id
when multiple devices are connected.
bundletool build-apks
--bundle=/ExampleApp/example_app.aab
--output=/ExampleApp/example_app.apks
--connected-device
If device flag attributes are omitted when building the APKs, the bundletool
will generate an APK set that will contain APKs for all possible devices.
Universal APK
The bundletool
can also create a universal APK by passing the universal
flag. This APK will contain all the files for all the device configurations. Because of that, it can be installed on any device. This will not by any means represent what the user will get when the app is installed from Play Store, however, this is a convenient way to pass an APK to users when you don’t know what device they are using.
bundletool build-apks
--bundle=/ExampleApp/example_app.aab
--output=/ExampleApp/example_app.apks
--ks=/ExampleApp/keystore.jks
--ks-pass=file:/ExampleApp/keystore.pwd
--ks-key-alias=ExampleKeyAlias
--key-pass=file:/ExampleApp/key.pwd
--universal
Testing Dynamic Feature Modules installation
When testing feature modules while building a universal APK, bundletool
will include only the modules that specify <dist:fusing dist:include="true"/>
in their manifest. If an attribute is set to false the definition of the activities will still be merged in the AndroidManifest.xml of the base module, however, the DEX files, Resources, Assets and Native libraries will not be.
A more convenient way of trying out the dynamic feature modules is by adding a local-testing
argument to the build-apks
command, which adds special metadata that will let us test feature module installation locally.
bundletool build-apks
--local-testing
--bundle=/ExampleApp/example_app.aab
--output=/ExampleApp/example_app.apks
Deploying APKs to a connected device or an emulator
After a set of APKs are created, bundletool
has the ability to extract the right combination of APKs from that set to a connected device or an emulator, by using the command install-apks
.
Note, when using the local testing
flag, bundletool
will read the metadata from the previous step and push all optional modules into the device’s local storage.
bundletool install-apks
--apks example_app.apks
Get APK size from an APK set
By providing the path of the APKs and adding the command get-size total
, bundletool
can measure the estimated download sizes as they would be server compressed over-the-wire. Adding the modules
flag would provide the exact size of the base module plus the specified module or modules.
bundletool get-size total
--apks=/ExampleApp/example_app.apks
--modules=module1
Support for Code Transparency for App Bundles
As of version 1.7.0 bundletool
has added support for adding and checking transparency, which ensures the app’s integrity. To be precise SHA256 hashes are created for each DEX file and each .so
file that is part of the App Bundle. Along with a singed code transparency file, the developer can verify the matching hashes using a singing key that is private to the developer. About how code transparency works and in-depth analysis on how to use bundletool
while adding, verifying an App Bundle or APK set, you can read more here.
Android App Bundle is Open Sourced through bundletool
With APK sizes going as light as possible, and functionalities like on-demand feature installations, the future of the bundle format is looking bright in the Android Ecosystem.
With open-sourcing bundletool
Google has indirectly open-sourced the App Bundle, meaning if any other distribution channels want to get in the action and implement support for bundles, they could with the help of bundletool
.
This tool has given app developers the means to manipulate the App Bundle. If you have not tried it yet, download this command-line tool from the Github repository and give it a go. Cheers.