Introduction
The Android App Bundle (AAB) is Android’s new, official publishing format. It offers a more efficient way to build and release your apps. AAB enables easier deliver of a great experience in a smaller app size, which can improve installation process. I will not go into to much details, but you can check more about Android App Bundle format and it’s benefits here: https://developer.android.com/platform/technology/app-bundle.
For start, let’s quickly check more evident cons and pros of AAB vs. “classical” APK.
Benefits
Manage releases more efficiently: Before AAB, if developer wanted to create a device-specific APK, several packages needed to be build and maintained. Let’s say, if you wanted to optimize APK for different resolution devices, several APKs needed to be build, maintained and deployed to Google Play Store. Now, with AAB, this is done automatically. AAB format slice down common and device-specific modules and deploys only needed packets onto installing Android device.
Smaller Apps: As stated before, with AAB Google Play Store deploys only device required artifacts. On deploy, it will not ship unused artifacts like: images with non-target device resolution, or binaries compiled for other-then-targeting CPU architecture, or language packs not installed/available on target device, etc…
Drawbacks
On the other hand, there are some drawbacks by introducing AAB into development process, most notable:
Testing: Application testing is maybe a little bit more difficult with AAB bundle format. With APK I could simply deploy APK to target Android device, install it and run. With AAB this is not an option. You can test you app with Google Play Store and Beta program, for example. On deployment, Google Play Store automatically identifies installing target device and ships only artifacts needed for that specific device.
As of this writing, Visual Studio AppCenter does not support AAB bundle format. This is very bad, because, especially for Xamarin developers, Visual Studio App Center is very popular tool to build, deploy and test of mobile apps – especially Xamarin.Forms.
As I can not not directly deploy and test my AAB bundles on my Android due to AAB format, I will show one possible solution to this situation. In the next two sections, I will show one relative simple approach how I can deploy and test my AAB-packed application on my local Android device.
How to split AAB to APK modules
Let’s say, I have my app packed in AAB bundle format. I described one way how to create AAB format for Xamarin.Forms application in my blog post entitled: Xamarin.Forms: Create Android App Bundles with Azure DevOps.
First, I need bundletool from Google. I can find this tool here: https://github.com/google/bundletool. In my case, I used (as of this writing) the latest release version: https://github.com/google/bundletool/releases/tag/0.12.0.
If I want to split my ABB on APK splits I run this command in my console:
1 2 3 4 5 6 7 |
java -jar bundletool-all-0.12.0.jar build-apks --bundle=si.jenx.mydemo-Signed.aab --output=.\out\si.jenx.mydemo-Signed.apks --ks=.\cert\Jenx.keystore --ks-pass=pass:xxxxxxx --ks-key-alias=JenxDemo --key-pass=pass:xxxxxxx |
In my “.\out\” folder I have si.jenx.mydemo-Signed.apks file. This file contains sliced down application on “elementary” modules. This *.apks file is basically compressed zip file.
If I want to create APK for my local connected device, I need adb (Android Debug Bridge, https://developer.android.com/studio/command-line/adb) which handles connection and deployment of my application from my development machine to connected Android device. Finally, I execute this batch script in my console:
1 2 3 4 5 6 7 8 9 10 |
set PATH=%PATH%;C:\Program Files (x86)\Android\android-sdk\platform-tools java -jar bundletool-all-0.12.0.jar build-apks --bundle=si.jenx.mydemo-Signed.aab --output=.\out\si.jenx.mydemo-Signed-connected-device.apks --ks=.\cert\Jenx.keystore --ks-pass=pass:xxxxxxx --ks-key-alias=JenxDemo --key-pass=pass:xxxxxxx --connected-device |
Now, I have these two files in in my .\out
folder:
1 2 3 4 |
Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 28. 01. 2020 22:07 71925637 si.jenx.mydemo-Signed.apks -a---- 28. 01. 2020 22:19 31240320 si.jenx.mydemo-Signed-connected-device.apks |
First file, containing all APK modules is approx 70MB in size. Second one is containing only artifacts for my local Android and it’s about 30MB in size. As said before, these two files are nothing more then compressed zip files – after unzipping I can observe content of both. First file contains sliced down application of all elementary parts: language packs, different resolution-resources packs, cpu-target packs and similar, e.g.:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
Mode LastWriteTime Length Name ---- ------------- ------ ---- ------ 1. 01. 1970 01:00 8895 base-af.apk ------ 1. 01. 1970 01:00 9123 base-am.apk ------ 1. 01. 1970 01:00 9078 base-ar.apk ------ 1. 01. 1970 01:00 7259519 base-arm64_v8a.apk ------ 1. 01. 1970 01:00 6703210 base-armeabi_v7a.apk ------ 1. 01. 1970 01:00 8974 base-az.apk ------ 1. 01. 1970 01:00 9180 base-be.apk ------ 1. 01. 1970 01:00 9173 base-bg.apk ------ 1. 01. 1970 01:00 9433 base-bn.apk ------ 1. 01. 1970 01:00 9004 base-bs.apk ------ 1. 01. 1970 01:00 8976 base-ca.apk ------ 1. 01. 1970 01:00 11169 base-cs.apk ------ 1. 01. 1970 01:00 8916 base-da.apk ------ 1. 01. 1970 01:00 11141 base-de.apk ------ 1. 01. 1970 01:00 9258 base-el.apk ------ 1. 01. 1970 01:00 17156 base-en.apk ------ 1. 01. 1970 01:00 11986 base-es.apk ------ 1. 01. 1970 01:00 8967 base-et.apk ------ 1. 01. 1970 01:00 8978 base-eu.apk ------ 1. 01. 1970 01:00 9128 base-fa.apk ------ 1. 01. 1970 01:00 8937 base-fi.apk ------ 1. 01. 1970 01:00 12064 base-fr.apk ------ 1. 01. 1970 01:00 8973 base-gl.apk ------ 1. 01. 1970 01:00 9255 base-gu.apk ------ 1. 01. 1970 01:00 5457100 base-hdpi.apk ------ 1. 01. 1970 01:00 9322 base-hi.apk ------ 1. 01. 1970 01:00 8978 base-hr.apk ------ 1. 01. 1970 01:00 9049 base-hu.apk ------ 1. 01. 1970 01:00 9104 base-hy.apk ------ 1. 01. 1970 01:00 8939 base-in.apk ------ 1. 01. 1970 01:00 8914 base-is.apk ------ 1. 01. 1970 01:00 11164 base-it.apk ------ 1. 01. 1970 01:00 9018 base-iw.apk ------ 1. 01. 1970 01:00 11492 base-ja.apk ------ 1. 01. 1970 01:00 9330 base-ka.apk ------ 1. 01. 1970 01:00 9127 base-kk.apk ------ 1. 01. 1970 01:00 9310 base-km.apk ------ 1. 01. 1970 01:00 9480 base-kn.apk ------ 1. 01. 1970 01:00 11140 base-ko.apk ------ 1. 01. 1970 01:00 9103 base-ky.apk ------ 1. 01. 1970 01:00 5448994 base-ldpi.apk ------ 1. 01. 1970 01:00 9130 base-lo.apk ------ 1. 01. 1970 01:00 9026 base-lt.apk ------ 1. 01. 1970 01:00 9026 base-lv.apk ------ 1. 01. 1970 01:00 19026989 base-master.apk ------ 1. 01. 1970 01:00 5436125 base-mdpi.apk ------ 1. 01. 1970 01:00 9149 base-mk.apk ------ 1. 01. 1970 01:00 9496 base-ml.apk ------ 1. 01. 1970 01:00 9124 base-mn.apk ------ 1. 01. 1970 01:00 9306 base-mr.apk ------ 1. 01. 1970 01:00 8939 base-ms.apk ------ 1. 01. 1970 01:00 9596 base-my.apk ------ 1. 01. 1970 01:00 8894 base-nb.apk ------ 1. 01. 1970 01:00 9571 base-ne.apk ------ 1. 01. 1970 01:00 8964 base-nl.apk ------ 1. 01. 1970 01:00 9146 base-pa.apk ------ 1. 01. 1970 01:00 11213 base-pl.apk ------ 1. 01. 1970 01:00 12567 base-pt.apk ------ 1. 01. 1970 01:00 9031 base-ro.apk ------ 1. 01. 1970 01:00 11832 base-ru.apk ------ 1. 01. 1970 01:00 9363 base-si.apk ------ 1. 01. 1970 01:00 9018 base-sk.apk ------ 1. 01. 1970 01:00 8986 base-sl.apk ------ 1. 01. 1970 01:00 8968 base-sq.apk ------ 1. 01. 1970 01:00 10121 base-sr.apk ------ 1. 01. 1970 01:00 8918 base-sv.apk ------ 1. 01. 1970 01:00 8947 base-sw.apk ------ 1. 01. 1970 01:00 9328 base-ta.apk ------ 1. 01. 1970 01:00 9461 base-te.apk ------ 1. 01. 1970 01:00 9200 base-th.apk ------ 1. 01. 1970 01:00 9002 base-tl.apk ------ 1. 01. 1970 01:00 11150 base-tr.apk ------ 1. 01. 1970 01:00 5477315 base-tvdpi.apk ------ 1. 01. 1970 01:00 9154 base-uk.apk ------ 1. 01. 1970 01:00 9161 base-ur.apk ------ 1. 01. 1970 01:00 8960 base-uz.apk ------ 1. 01. 1970 01:00 9023 base-vi.apk ------ 1. 01. 1970 01:00 5461538 base-xhdpi.apk ------ 1. 01. 1970 01:00 5471668 base-xxhdpi.apk ------ 1. 01. 1970 01:00 5474969 base-xxxhdpi.apk ------ 1. 01. 1970 01:00 13535 base-zh.apk ------ 1. 01. 1970 01:00 8956 base-zu.apk |
Second file is my local-device-specific. It contains only needed modules for my Android device. The content is significantly reduced, as you can see below:
1 2 3 4 5 6 7 8 |
Mode LastWriteTime Length Name ---- ------------- ------ ---- ------ 1. 01. 1970 01:00 6703210 base-armeabi_v7a.apk ------ 1. 01. 1970 01:00 11141 base-de.apk ------ 1. 01. 1970 01:00 17156 base-en.apk ------ 1. 01. 1970 01:00 19026989 base-master.apk ------ 1. 01. 1970 01:00 8986 base-sl.apk ------ 1. 01. 1970 01:00 5471665 base-xxhdpi.apk |
I have 3 languages installed or enabled on my Android device: Slovenian, English and German – and this is reflected also my output: only these three locales will be deployed on my device when I download app from Google Play. Furthermore, my device has xxhdpi-based density display, thus, only xxhdpi-based resources will be shipped on my device on installation. And because my Android phone is running on armeabi-v7a 32-bit ARM-based CPU – only binaries for this CPU will be installed. Pretty awesome.
So, AAB is sliced-down to minimum – it contains only required APK modules for my device. Google Play Store handles uploaded AAB file exactly the same way. It slice down AAB on all possible variants and deploys only optimal application, all because it knows your target device configuration.
Install AAB on my local Android device
As before, for installation AAB packed application on my locally connected Android, I will again use Google bundletool and Android Debug Bridge (or adb). Script command for deploying my app onto my locally connected Android Device is as follows:
1 2 3 4 |
set PATH=%PATH%;C:\Program Files (x86)\Android\android-sdk\platform-tools java -jar bundletool-all-0.12.0.jar install-apks --apks=.\out\si.jenx.mydemo-Signed-connected-device.apks |
After I run this script, my app is successfully deployed on my Android.
In the next section I will compare the installed application size, pushed via “classical” APK or with AAB bundle.
Comparing app size deployed with APK vs. AAB
I checked my apps size deployed with APK and with target specific AAB deploy. The result is:
I reduced the app size for approx. 21%. Awesome, do you agree?
You can also check some AAB dynamic delivery improvements for some popular Google apps: https://developer.android.com/platform/technology/app-bundle#size-savings-because-of-dynamic-delivery
Conclusion
AAB bundle format is relatively new deployment format for Android applications. It brings many benefits, some of them are also mentioned in this blog post.
In the future, AAB will be de-facto-standard to deploy Android based apps on Google Play Store. Google is really pushing hard in this direction.
In this blog post I quickly investigated AAB bundle format and how to install and test ABB-bundle-based applications on locally connected Android Devices.
Until next time, happy coding.