Building an Android App Bundle

bundleRelease builds the .aab that Play requires of new apps; assembleRelease builds one universal APK for other stores and for sideloading. With the upload key supplied through the environment:

Building BookNest 1.0.0 as a signed bundle and APKKotlin
. ~/keys/booknest-kt.env        # exports the three ORG_GRADLE_PROJECT_BOOKNEST_UPLOAD_* values
nice -n 10 ./gradlew --no-daemon --max-workers=2 bundleRelease assembleRelease
ls -l app/build/outputs/bundle/release/app-release.aab app/build/outputs/apk/release/app-release.apk
Output
BUILD SUCCESSFUL in 11m 57s
117 actionable tasks: 117 executed
-rw-r--r-- 1 dev dev 4422522 Sep 25 10:47 app/build/outputs/apk/release/app-release.apk
-rw-r--r-- 1 dev dev 9441154 Sep 25 10:48 app/build/outputs/bundle/release/app-release.aab

The bundle is larger because it carries files no phone downloads, in a BUNDLE-METADATA folder that Capacitor 243,123 's and React Native 36,878 's bundles (Signed App Bundle and Publishing BookNest) never looked into:

What the bundle carries besides the appShell
unzip -l app/build/outputs/bundle/release/app-release.aab | grep -E "BUNDLE-METADATA|bookclub/dex"
Output
    41828  1981-01-01 01:01   BUNDLE-METADATA/com.android.tools.build.libraries/dependencies.pb
 69955279  1981-01-01 01:01   BUNDLE-METADATA/com.android.tools.build.obfuscation/proguard.map
    13259  1981-01-01 01:01   BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof
...
     6840  1981-01-01 01:01   bookclub/dex/classes.dex

proguard.map is R8 234 's mapping file (R8 Full Mode), 70 MB of it, which Play uses to deobfuscate crash reports without a separate upload. baseline.prof is the compiled baseline profile of Baseline Profiles, which Play puts into every APK it builds (the universal APK has it as assets/dexopt/baseline.prof). dependencies.pb lists every library and version; Play Console 1 inspects it to alert you to known issues in the SDKs you ship (dependenciesInfo { includeInBundle = false } opts out). bookclub/ is Feature Delivery's feature module, shrunk by the same R8 run as the base.

Bundletool (Signed App Bundle; $BT runs its JAR, $AAB is the bundle) splits the bundle the way Play will and reports what a phone downloads:

The download size of BookNest for each ABIKotlin
$BT build-apks --bundle=$AAB --output=booknest.apks --ks=$HOME/keys/booknest-kt-upload.jks \
  --ks-key-alias=upload --ks-pass=pass:$BOOKNEST_UPLOAD_PASSWORD
$BT get-size total --apks=booknest.apks --dimensions=ABI
Output
ABI,MIN,MAX
x86,3266083,3307204
x86_64,3269782,3310913
arm64-v8a,3262280,3303409
armeabi-v7a,3260285,3301408

A phone downloads about 3.3 MB, whatever its ABI, because the only native code is four small AndroidX 234 libraries (Play Policies); adding --modules=bookclub showed the Book Club costs 6.7 KB more.