Android App Bundles, how to generate APK from AAB

tl;dr:
Q: How to send .aab files to Android users?
A: TestFairy allows .aab app distribution to Android apps.
——

And now for the long version 🙂

Google recently announced that “From August 2021, new apps will be required to publish with the Android App Bundle (AAB) on Google Play”. For those who haven’t got the chance to play with app bundles yet, we are going to take a closer look.

Structure of an App

In the traditional workflow, an Android app is compiled into an APK file. APK files are ZIPs of compiled java code, XML layouts, native library binaries and other resources. To be able for an APK to support all Android devices, it has to ship necessary binaries for all kinds of CPU architectures. Moreover, app resources such as images and videos must be shipped multiple times to support various screen sizes.

This whole portability approach creates bloated APKs, sometimes consists of more than ~75% percent of unused data. App bundles are invented to solve this problem.

Ideally, we want a user to download an APK with only relevant files. For instance, a phone with an ARM CPU should download an APK that only ships ARM binaries. Binaries of architectures such as x86, x86_64 should not be included. A smart watch app will only need low resolution images.

New Approach

To tackle this issue, we instruct android compiler to create an AAB (app bundle) file instead of an APK.

./gradlew app:bundleDebug

Unlike the traditional ./gradlew app:assembleDebug, the command above will create an app bundle.

An AAB file has all the data a traditional APK build has. It also includes additional meta data to figure out how to create smaller APKs by cherry picking relevant files from its content.

When it comes time to release a new version of our app on Google Play store, we upload this AAB file to Google servers. Behind the scenes, Play servers run a tool called bundetool and create tens, if not hundreds of APK files, tailored specifically for any device out there.

Since Google Play store is not the only distribution platform for Android, we are free to use bundletool ourselves to create the final APKs.

How to bundletool

Bundletool is a command line java program. It consumes a single AAB file to create an APKS (not to confuse with APK) file.

The name APKS stands for “APK sets”. You can think of them as collections of multiple APK files.

APKS are ZIP files too. They include partial APK files called “splits”. You will find a split APK for every kind of variance an app can have. i.e there will be a split just for the French localization, another for x86 CPUs, another for xhdpi screens etc.

Here is an example APKS file, extracted as ZIP:

As you can see, it consists of small APK files of different device specifications. When we call the bundletool CLI, we are given the option to declare what kind of devices we want to support. Our specs determines how many APK files there will be in the our target APKS file.

Here is an example command to create an APKS from an AAB, using the spec of the connected Android device:

bundletool build-apks --connected-device --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks

How to install an APKS file

There are two options here.

We can extract APKS content out and install each APK with the command below:

adb install-multiple [-lrtsdpg] <file...>
                             - push this package file to the device and install it
                               (-l: forward lock application)
                               (-r: replace existing application)
                               (-t: allow test packages)
                               (-s: install application on sdcard)
                               (-d: allow version code downgrade)
                               (-p: partial application install)
                               (-g: grant all runtime permissions)

adb install-multiple first.apk second.apk third.apk ...

Alternatively, we can use the built-in command in bundletool to do the trick for us:

bundletool install-apks --apks=/MyApp/my_app.apks

How to create an APK from an AAB without losing portability

If you require to remain working with the old workflow in your testing environment, as in distributing a single APK to all of your users the traditional way, you can instruct bundletool to do that.

These portable APK files are called universal packages, which can be produced with the command below:

bundletool build-apks --mode=universal --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks

This command will also create an APKS file but if you take a look at its ZIP contents, you will find only a single APK called universal.apk. You can safely distribute this APK to your users, knowing it will work on all devices.

App bundle (AAB) Distribution with TestFairy

Starting from June 2021, we are adding the option to upload AAB files via our web dashboard, REST API and other means to TestFairy. Make sure you try and let us know if we can improve it further!

Until next time, #staysafe