Signed App Bundle

Building a Signed Android App Bundle

Google Play 1 has required new apps to upload an Android App Bundle (.aab) since August 2021. A bundle holds the code and resources for every device, and Play cuts it into APKs per ABI, screen density and language. bundleRelease builds it; assembleRelease makes one APK for other stores. Build and sync first, because a release packages whatever web assets the last sync copied:

Building BookNest's signed bundle and APKShell
npm run build && npx cap sync android
cd android
./gradlew bundleRelease assembleRelease --no-daemon
ls -l app/build/outputs/bundle/release/*.aab app/build/outputs/apk/release/*.apk
keytool -printcert -jarfile app/build/outputs/bundle/release/app-release.aab | grep Owner
Output
...
BUILD SUCCESSFUL in 1m 45s
943 actionable tasks: 44 executed, 899 up-to-date
-rw-r--r-- 1 dev dev 18384375 Sep 25 03:28 app/build/outputs/apk/release/app-release.apk
-rw-r--r-- 1 dev dev 13574455 Sep 25 03:28 app/build/outputs/bundle/release/app-release.aab
Owner: CN=BookNest Upload, O=Example Books, C=MY

The APK is larger because it carries native libraries for four ABIs. To see what a phone downloads, Google's bundletool 4,040 (github.com/google/bundletool (https://github.com/google/bundletool 4,040 ), Apache-2.0, 1.18.3, one JAR) splits the bundle as Play does and installs the result:

Splitting the bundle as Play does and installing it
BT="java -jar $HOME/tools/bundletool-all-1.18.3.jar"
AAB=app/build/outputs/bundle/release/app-release.aab
$BT build-apks --bundle=$AAB --output=booknest.apks --ks=$HOME/keys/booknest-upload.jks \
  --ks-key-alias=upload --ks-pass=pass:$BOOKNEST_STORE_PASS
$BT get-size total --apks=booknest.apks
$BT install-apks --apks=booknest.apks --device-id=emulator-5558
adb -s emulator-5558 shell dumpsys package com.example.booknest | grep -E "versionCode|versionName"
adb -s emulator-5558 shell run-as com.example.booknest ls
Output
MIN,MAX
9460043,9996223
The APKs have been extracted in the directory: /tmp/7005752457619800063
    versionCode=10000 minSdk=24 targetSdk=36
    versionName=1.0.0
run-as: package not debuggable: com.example.booknest

A phone downloads under 10 MB: the base APK plus one split each for its ABI, density and language. run-as refuses because a release build is not debuggable, which also keeps WebView debugging off (Remote Debugging Android); this userdebug emulator image still exposes every WebView to DevTools, so check that on a real phone.