Optimized delivery of great experiences with Android App bundle

Android Mar 28, 2020

At Halodoc, we are constantly looking for ways to simplify health care for users across Indonesia. As a virtual healthcare platform, one of our main goals is to reach more people irrespective of their technological constraints (memory, network, etc). Optimising for memory is one such effort and Android app bundles come to our rescue here.

Having a large app size has potential downsides like:

  1. Slower downloads
  2. Lower conversion rates
  3. Higher uninstalls
  4. Lower update rates, thereby resulting in a highly fragmented user base

We have tried various strategies to reduce our app size:  

  1. Obfuscation and Resource shrinking : We used Proguard and R8 to remove all of the unused resources from our app and shorten the names of classes & members. This reduced our DEX file sizes.
  2. We tried using ABI configurations by creating multiple APKs that contain files for specific screen densities.
  3. We tried using different image compression techniques, by writing scripts that compressed all the images in the available density buckets.
  4. We started using vector images instead of PNGs and JPEGs as vector images are lighter and do not require different images for different density buckets.

The above strategies worked to an extent, but still there was scope for further improvement. With this in mind, we finally tried Android App Bundle, which was a game changer.

So what is Android App Bundle?  

An Android App Bundle is a new upload format that includes all your app’s compiled code and resources, but defers APK generation and signing in to Google Play. It generates different .aab (Andoid App Bundle) files based on the underlying device processor architecture unlike the traditional way where it is distributed using an Android Package(.apk).

After the app bundle generation, optimised APKs are generated based on the user’s device configuration using Google's new app serving model called Dynamic Delivery. This only downloads the code and resources required to run your app. We no longer have to build, sign and manage multiple APKs to support different devices. Consequently, users get smaller, more optimized downloads.

How we benefited by using App Bundles?

After using the App Bundle, our app size decreased drastically.

As shown on the graph above, our app size was around 30-32 MB. After we implemented App Bundle, it reduced to 18-20 MB. A staggering ~50% improvement.

How to build an app bundle?

There are multiple ways to generate an App Bundle:

  1. Using Android Studio : You can easily build your app bundle using Android Studio(3.2 and above) by following these steps -

    a. Go to Build > Generate Signed Bundle(s)/APK
    b. Select Android App Bundle option and continue
    c. Provide the key store path and fill the necessary information such as: key store password, key password etc. Make sure the Export Encrypted Key option is enabled
    d. Select the build variants for which bundles have to be generated and proceed to finish. If destination folder has not been changed, the generated app bundle will be stored at:  app/build/outputs/bundle/buildVariant.

2. Using Gradle:  Generate an app bundle from the command line

./gradlew : bundle

Google play app signing

App Signing is a process in which Google manages and protects the app's signing key and uses it to sign your APKs/App Bundles for distribution. Once we have provided the Play Console with our app signing key, we can upload our APK and Google will sign them for us prior to delivering it to our users.

Though this is optional for developers if they are distributing APK format, App Bundle format mandates the Google App Signing as a process. This is because when it comes to App Bundles, Google Play needs to be able to sign the APKs for you before distribution.

Testing app bundle format

Author: Chidambara MR

Moving to App Bundles to reduce the apk size was beneficial, but testing scenarios were an uncharted territory. We have adopted the following tools and methods to make the migration easy and risk-free:

  1. Using bundle tool (Play store uses the same while delivering the device specific apks)
  2. Using an internal test tracker

Using bundle tool

Bundle tool is the underlying tool used by Playstore which converts App Bundles to device specific apks.

Download bundle tool from here - https://github.com/google/bundletool/releases

Bundle tool can be used as a command line tool

java -jar bundletool-all-0.12.0.jar build-apks
--bundle=/<folder_to_aab>/my_app.aab 
--output=/<folder_to_apk>/my_app.apks
--ks=/MyApp/keystore.jks
--ks-pass=file:/MyApp/keystore.pwd
--ks-key-alias=MyKeyAlias
--key-pass=file:/MyApp/key.pwd

Bundle tool options:

  1. build-apks This option is used to generate the APK files from the app bundle
  2. --bundle Specifies the path of the bundle file
  3. --output Specifies the path of the file (referred to as the APK Set) into which the APK files will be generated
  4. --ks Specifies the path of the keystore file. This is needed to sign the generated apks
  5. --ks-pass Specifies the path of the keystore password file
  6. --ks-key-alias Specifies the alias provided when the key was generated

The above command extracts the apks from the app bundle and stores it in /<folder_to_apk>/my_app.apks. Again we have to pick the device specific apk to install in the connected device.

java -jar bundletool-all-0.3.3.jar install-apks --apks=/tmp/MyApks.apks

This command will instruct the bundle tool to identify the appropriate APK files for the connected device and install them so that the app can be launched and tested.

To avoid this manual procedure, we have used the below shell script. It accepts the path of the app bundle as input and will install the device specific apk to the connected device

#!/usr/bin/env bash
​
#To install signed apk to the connected device from bundle format.
​
set -e
set -o pipefail
​
#Paths specific to system, change accordingly
readonly KEYSTORE_PATH=<keystore path>
readonly KEYSTORE_PASS=<keystore password>
readonly KEYSTORE_ALIAS=<keystore alias>
​
​
# Do not modify below content
readonly PASS=pass:${KEYSTORE_PASS}
​
if [ -z "$BUNDLE_HOME" ];then
echo "error: BUNDLE_HOME not set"
exit
fi
​
alias bundletool="java -jar $BUNDLE_HOME"
​
if [ -z "$1" ];then
echo "error: missing bundle file path"
exit
fi
​
rm -f android.apks
java -jar $BUNDLE_HOME build-apks --bundle=$1  --connected-device --output=android.apks --ks=${KEYSTORE_PATH} --ks-key-alias=${KEYSTORE_ALIAS} --ks-pass=${PASS}
echo "[NOTE:Generated apk is specific to the connected device]"
java -jar $BUNDLE_HOME install-apks --apks=android.apks && echo "APK installed on device!"

Note: Replace KEYSTORE_PATH, KEYSTORE_PASS, KEYSTORE_ALIAS with your keys

  1. Keep the shell script in some folder
  2. Set bundle home path
  3. Run this command in the terminal

sh ~/<path of shell script>/pharmacy.sh ~/<path of bundle file>/<app>.aab

Once you run the above command, the bundle tool will extract the relevant apk and install it in the connected device.

Using internal test tracker

Developer uploads the bundle file to internal test tracker. Through the internal test tracker, the app is made available to up to 100 designated internal testers. This is the fastest way to get the app to a small group of known testers. A list of authorised testers may be specified by selecting the app from within the Google Play console. Internal testers can get the access by signing into the internal test tracker. Once they get the access, they can download the app from the play store for testing.

Device coverage

Choosing the right set of devices to test the App Bundles install /update is crucial to uncover any issues due to the app bundle migration.

Our strategy is to cover the most of the devices our user base has and run the following sample scenarios:

  1. Device specific resources
  2. Device specific libraries
  3. Device specific assets

Conclusion

In this article we learnt how we can reduce our app size using Android App Bundle. This will help in:

  1. Higher app install on play store
  2. Higher app update rate
  3. Having latest app translates to fewer errors and the latest features.
  4. Fewer forced app force.

Join us
We are always looking out to hire for all roles in our tech team. If challenging problems that drive big impact enthral you, do reach out to us at careers.india@halodoc.com


About Halodoc

Halodoc is the number 1 all around Healthcare application in Indonesia. Our mission is to simplify and bring quality healthcare across Indonesia, from Sabang to Merauke.
We connect 20,000+ doctors with patients in need through our Tele-consultation service. We partner with 1500+ pharmacies in 50 cities to bring medicine to your doorstep. We've also partnered with Indonesia's largest lab provider to provide lab home services, and to top it off we have recently launched a premium appointment service that partners with 500+ hospitals that allows patients to book a doctor appointment inside our application.
We are extremely fortunate to be trusted by our investors, such as the Bill & Melinda Gates foundation, Singtel, UOB Ventures, Allianz, Gojek and many more. We recently closed our Series B round and In total have raised USD$100million for our mission.
Our team work tirelessly to make sure that we create the best healthcare solution personalized for all of our patient's needs, and are continuously on a path to simplify healthcare for Indonesia.

Hemraj Singh

Among with Chidambara M R

Android Developer at HaloDoc ID