The App Bundle is a new delivery format for Android apps that helps to deliver an optimized version of your APK by just including what your users need, reducing your app size and making your users happier. :]
Normally, when users download your app, they get what is called a universal APK. This is a file that contains all resources for all device configurations, like images, strings, layouts, and more. Users will not need all of them, which wastes space and leaves less room for apps or games. 😿
With App Bundles, your users will receive a special version of your APK that only includes the language, screen density and resources they need per unique user configuration.
Imagine one of your users has selected English as their default language, and that their device supports extra-extra-high-density (aka xxhdpi). Using App Bundles, the Google Play Store is only going to download an APK file with value-en/strings.xml and xxhdpi resources, reducing the required space and cost of the app.
How Are App Bundles Useful?
Space is one major reason why a user will install or uninstall your app. When users download a new app, they have to take two things into consideration: data and storage consumption.
If your app is too big, users may have to uninstall one or more other apps in order to install yours.
Another trade-off is how much data your app is going to cost them, depending on their data plan. Users often have limited mobile data plans, which means that downloading your app may put users in a tricky situation. They will need to decide what’s more important: streaming videos or downloading your app.
You don’t want to be the app that increases their phone bill, right?
Having a light APK will help you to attract new users to your app and keep existing users. :]
CountOnMe is an app that displays a number from 1 to 10, every time you swipe. You’re going to use it to see how to use App Bundles in practice, by generating and evaluating the content of different APKs.
Download the CountOnMe project using the Download Materials button at the top or bottom of this tutorial. Open the project in Android Studio 3.2 or later by selecting Open an existing Android Studio project on the Android Studio welcome screen:
There is no final project for this tutorial, since you’ll simply use CountOnMe to explore the App Bundle tools in Android Studio.
Before continuing with the tutorial, take a look at the project.
Exploring the CountOnMe Structure
The source code is structured as follows:
This is the entry point of the app.
default resources in English strings, dimens etc .
default resources in Spanish strings, dimens etc .
default resources in French strings, dimens etc .
As you can see in the above image, there are many more files that weren’t mention for brevity. But the main idea is that you can see the different resources that the app has. When you use App Bundles, you’re going to generate different APK versions that only include some of these resources.
Generating an App Bundle
App Bundle is a new format called
.aab (Android App Bundle), that you upload to the Play Store instead of the traditional
apk. With this new format, the Play Store will generate many different variations of your APK, depending on your user’s device configuration.
App Bundles take advantage of a concept called split APK. As its name suggests, a split APK is similar to a normal
.apk. The difference is that a split APK file can be broken into separate small pieces, one containing the base code and other small APKs containing the app resources that can be installed later.
The beauty of splits is that the Android operating system treats the app as a whole, and each split is a small fraction that can be added independently. It’s like one app with small Lego blocks to add on.
To see how an App Bundle is structured, you’ll generate one for the CountOnMe app.
Go to Build ▸ Build Bundle(s) / APK(s) ▸ Build Bundle(s) in the Android Studio menu.
Android Studio will show you a prompt for where to find the file. Press locate to open the file location in your file system viewer, e.g., the Finder on macOS.
In this case, you’ll use the tool
unzip, but you can use any similar tool you like. Open Terminal and navigate to the directory containing the app.aab file. Run the following.
Alright, now you can see the structure of an
base/, feature1/, and feature2/
Top level folder that contains each module of your app. In the case of CountOnMe, you only have one
basedirectory, because you just have one module. The
basedirectory always contains the main module of your app. Each dynamic feature module will have it’s own
Metadata files that may include ProGuard mappings and the list of your app’s DEX files. This directory is only going to be available when proguard is enabled.
Module Protocol Buffer (*.pb) files
Provides metadata that describes the contents of each app module to the Play Store. For instance,
BundleConfig.pbprovides information about the bundle itself, like which version of the build tools were used to build the App Bundle.
Contains the DEX files for each module in a separate directory.
res, lib, and assets
These folders are used in the same way as a typical APK, except that for an App Bundle, they’re used by Google Play to package only the files that satisfy the target device configuration.
This directory stores files that are later relocated to the root of the APK(s) that include the corresponding module.
The only thing you have to do to use an App Bundle is create an
.aab and upload it to the Google Play Store. The Play Store will handle everything from creating multiples version of your APK, to selecting the right one for your users.
Creating a Signed App Bundle From Android Studio
Go to Android Studio ▸ Build ▸ Generate Signed Bundle / APK.
Introduce your app signing configuration and click Next.
On the next screen, choose a Destination Folder and Build Type, and then click Finish. Simple. :]
Creating an App Bundle From the Command Line
With the availability of App Bundles, you now have some new Gradle tasks to produce an
bundle task for CountOnMe, from the project root folder, in this case countonme-starter:
You will see that the app.aab file is generated at the following path.
You can use the following commands to create the app bundle for a specific build variant.
buildVariant could be the
The location of the output file will be:
The same signing process used for traditional APKs is compatible with App Bundles.
Publishing an App Bundle in the Play Store
To publish your App Bundle to the Play Store, the first thing you need do is enroll in App Signing by Google Play. After enrolling, you can manage your releases as you did with APKs.
After uploading your App Bundle, you have the opportunity to review your release.
The Google Play console will generate all the APKs for your user configurations. A nice tool for visualizing all those APKs is Bundle Explorer.
Go to Release Management ▸ Artifact library, then select one of the bundles that you have uploaded and click EXPLORE
Now you can see all the savings that an App Bundle provides, and all the APK files that it generated.
You can go even deeper by clicking VIEW DEVICES, and see the specific devices that an APK is going to be delivered to.
The Bundle Explorer can be a great tool while debugging, when you want to know the exact file that a user received on their device.
App Bundles are also available in the Publishing API for automation.
Testing App Bundles
The Google Play Store provides a convenient way to test your App Bundle called Internal Test Track. This is a special track wherein you can invite a closed list of users to test your app.
The Internal Test Track is similar to the Alpha and Beta tracks. The difference is that you don’t have to wait very long with the Internal Test Track, because it’s available almost instantly after you upload your App Bundle file. That helps to ensure that what your users are going to receive is the same as what your QA team is testing.
There you can create a list of up to 100 testers.
You can then share the Opt-in URL link with your testers. This link allows the users on the test list to download your app.
Bundletool is a command-line tool that helps you to manipulate Android App Bundles. This is the same tool that the Play Store uses to generate
.apk files from a
.aab file. Additionally, the source code of Bundletool is available as an open source project on GitHub, in case you want to take a deeper look at its ins and outs.
Bundletool allows you to test locally and simulate the same process that Google Play does to serve your App Bundle to users, in case you don’t want to test through the Play Store.
It’s your turn to play a bit with Bundletool. :]
Go to the Bundletool release page and download the bundletool-all-[LAST-VERSION].jar file into a new directory called testing-app-bundle. Then rename the jar to bundletool.jar, and copy the debug
.aab file that you previously generated to this same directory.
After that, you should have a directory similar to this one:
.jarfile, so to be able to use it, you need to install Java Runtime Environment. Make sure you have JRE installed before going forward. As an Android developer, you likely have a JDK already installed, which includes a JRE.
To execute Bundletool from the command line, you need to use
java -jar bundletool.jar followed by any command that you want Bundletool to execute.
Try this with
build-apks. This command takes an App Bundle (
.aab) file and outputs a set of APKs. To indicate the bundle, you use the argument
--bundle, and output is identified with the argument
Open Terminal, navigate to the testing-app-bundle directory and run the following:
java -jar bundletool.jar build-apks --bundle=app.aab --output=app.apks
After executing the command above, you have a file app.apks:
java -jar bundletool.jar build-apks --bundle=app.aab --output=app.apks --ks=keystore.jks --ks-pass=<your_keystore> --ks-key-alias=<your_key_alias> --key-pass=<your_key>
Pro-tip: If you use the flag
--connected-device, you can generate APKs just for the devices connected to your development machine.
To install your app on a device, you use the command
install-apks, which takes an APK set as an input with the argument
--apks, then extracts it and installs the corresponding APK on a connected device.
java -jar bundletool.jar install-apks --apks=app.apks
Internally, Bundletool will read the configuration of the connected device and will select the APK that matches the configuration in order to install it on the device. This is the same matching process that the Google Play Console does when a user requests an app.
Using Bundletool, you can replicate the same process that Google Play uses. This is a great tool for testing locally.
You’ve seen just a small set of things you can do with Bundletool. You can find more in the complete reference.
A Closer Look at Bundletool Output
You’ll now take a closer look at the APK set file app.apks in the testing-app-bundle folder. Change the extension of app.apks to app.zip and uncompress it using your favorite unzipping tool.
Now you have an app directory. Inside this directory there’s a sub-folder called splits. In there, you can find all the APK variations.
Now, try a small experiment, taking one of these split APKs and comparing it with a traditional APK.
You’ll take the base-es.apk file and open it with the
APK Analyzer tool in Android Studio, by going to Build ▸ Analyze APK.
Navigate to the splits folder in the test-app-bundle directory you made, choose base-es.apk and click OK.
base-es.apk is a small file of just 5.3 KB, and it only contains the string resources for the Spanish language.
Now for the other side of the coin, a traditional (universal) APK file. A universal APK contains all the resources for every possible device configuration your app supports, and it’s the traditional way to distribute an app.
Go to Build ▸ Build Bundle(s) / APK(s) ▸ Build APK(s):
Then choose the APK file in app/build/outputs/apk/debug:
As you can see above, the universal APK has everything in it! It’s a much bigger 2.6 MB vs 5.3 KB file, like comparing an 🐜 versus an 🐘.
APK Analyzer allows you to diff two APKs, by going to the upper right corner and clicking the Compare with previous APK button, then navigating to and choosing the base-es.apk file:
Here’s the diff between the universal APK and base-es.apk:
Now you see the real power of App Bundles in action!
Another great feature of App Bundles is dynamic delivery, which helps your apps get even smaller!
The idea is that you can split your apps by feature modules in such a way that parts of your app that are not as popular can be downloaded on-demand, only when the user needs them and not as part of your main APK. It’s the same idea as that of downloading resources, but with code instead. Pretty cool! :]
This feature of App Bundles is currently in Beta, so to be used in production you have to opt-in.
Devices on Android 4.4 (API level 19) and lower do not support split APKs, which are the foundation of delivering multiple APK files to devices. Google Play serves a single APK version that includes resources for all languages that your app supports on those Android versions. For backwards compatibility, you don’t have to take any additional steps, since Google Play takes care of everything for you.
Where to Go From Here?
Now that you’ve gotten started with App Bundles, you should try using App Bundles with your own apps and publish an Internal track on the Google Play Store. You can also test your App Bundles locally using Bundletool.
I hope you enjoyed this introduction to App Bundles. If you have any comments or questions, please join in on the forum discussion below!