In a previous article we've learned how to build an APK executable for Android from the command line, without using an IDE. Let's advance further and build an Android App Bundle (AAB). Only the JDK, the Android SDK and the Bundletool will be used. The steps described below were tested in Windows, but the same commands can be adapted to any other environment.
What is Android App Bundle (AAB)?
Currently AAB is the preferred format to publish applications to Google Play. This publishing format contains all the application compiled code and resources. The APK generation and signing is deferred to Google Play. In this way the APK can be optimized by including only the code and resources that are needed for a specific device. Therefore, the download size can be reduced significantly.
For example, let's suppose that our app supports both smartphones and Android TV. For compatibility with Android TV we've created a hi-res banner image. If we publish the app in APK format our banner image will be downloaded to the smartphone devices, even though it will never be used there. The AAB format makes it possible to avoid including unnecessary data to speed up the download, save bandwidth and storage space.
At the time of writing the AAB format is used by Google Play only, it is not supported by other stores.
Why not using an IDE?
Android Studio can build an AAB automatically with a single click. Doing it manually may be useful for learning purposes. For example, if you are building your own tool to generate Android applications, this article can be used as a reference. There are special cases when it can be necessary to avoid using autogenerated code. In such cases you may need to build the package manually.
The tools of trade
We'll only need the JDK, the Android SDK and the Bundletool. The JDK is necessary to compile the Java code and pack the binaries. It can be used to generate the certificate for signing as well. The Android SDK contains the necessary tools to convert the bytecode to Dex format (Dalvik Android virtual machine), align and sign the bundle. The Bundletool is used to generate the AAB. It is also used to test the AAB locally, by generating the device specific APKs.
If you don't already have a JDK 1.6 or later installed you can download it from the Oracle website. Make sure to install the Java Development Kit (JDK), not just the runtime. It's recommended to configure the environment variable JAVA_HOME to point to the Java installation location (without including the bin subdirectory). This is not mandatory, but it can help the Java tools locate the correct JDK version, especially if you have multiple JDK versions installed.
The Android SDK installation is trickier. Google doesn't provide the SDK as a standalone installation package any longer. There are 2 alternatives:
- Install the Android Studio from the official website. From the IDE homepage you can install the SDK easily.
- Another option is to download and install the Command Line Tools, which are available at the bottom of the same official website. The Command Line Tools are not the Android SDK. After installing the Command Line Tools you can launch the sdkmanager to download and configure the Android SDK.
The Android SDK Build Tools should be at least version 29.0.2. Previous versions may not include the AAPT2 tool or there may be compatibility issues. You can also download the latest AAPT2 version from Maven as explained here.
The latest Bundletool can be downloaded here. It is provided as a single JAR file.
A complete sample project containing the Java source code and the Windows batch files to build and run the Android application is available in our GitHub repository.
We recommend creating your own certificate to sign the bundle. The JDK keytool can be used to replace the sample certificate with your own:
del src\demo.keystore /q REM The following command is a single line "%JAVA_HOME%"\bin\keytool -genkey -keystore src\demo.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias demo
The path src\demo.keystore can be changed if you want to store the certificate into a different location. If you didn't configure the JAVA_HOME environment variable, the full path must be specified when calling the keytool. The certificate validity and the alias name can be changed, if necessary. The keytool will prompt you to fill in some information about the organization, location and assign a password. Our password for demo.keystore is password (not really strong).
Before running build.bat it's necessary to setup the following configuration parameters. A plain text editor like Notepad can be used to edit the build.bat file:
- BUILD_TOOLS is the location of the Android SDK Build Tools. Use the example value as a reference.
- ANDROID_JAR is the path to the android.jar for the required API level. It is recommended to use the latest API version. It doesn't prevent the APK from running on older Android versions unless the app uses new version specific features.
- BUNDLETOOL is the location of the Bundletool jarfile. Try to use the latest version, if possible.
Let's review what the batch file does step by step:
- Compile the resources. This command parses the Android resources (images, xml and so on) and packs them into a ZIP file. Notice that in order to build an AAB we are using the AAPT2 tool instead of AAPT.
"%BUILD_TOOLS%\aapt2" compile --dir res\ -o obj\res.zip
- Link the resources. This is a single line:
"%BUILD_TOOLS%\aapt2" link --proto-format -o obj\linked.zip -I "%ANDROID_JAR%" --manifest src\AndroidManifest.xml --java src obj\res.zip --auto-add-overlay
- Compile the Java sources to bytecode.
"%JAVA_HOME%\bin\javac" -d obj -classpath src -bootclasspath "%ANDROID_JAR%" src\com\celer\hello\*.java
- Convert the bytecode to Dex format (Dalvik Android virtual machine).
"%BUILD_TOOLS%\dx" --dex --output=bin\classes.dex obj
- Combine the resources and the bytecode into a single bundle:
cd obj "%JAVA_HOME%\bin\jar" xf linked.zip resources.pb AndroidManifest.xml res mkdir manifest dex 2>nul move AndroidManifest.xml manifest copy /Y /B ..\bin\classes*.dex dex\ 2>nul "%JAVA_HOME%\bin\jar" cMf base.zip manifest dex res resources.pb
- Build the AAB.
"%JAVA_HOME%\bin\java" -jar "%BUNDLETOOL%" build-bundle --modules=base.zip --output=..\bin\hello.aab
- Sign the AAB.
"%JAVA_HOME%\bin\jarsigner" -keystore ..\src\demo.keystore -storepass password ..\bin\hello.aab demo
If there are no errors the output will be an AAB ready to be published to Google Play.