App Bundle (AAB)

Build Android App Bundles for Google Play Store

📦 What is an App Bundle?

Android App Bundle (AAB) is Google's publishing format for Android apps. It's smaller than APK and allows Google Play to generate optimized APKs for each device configuration, reducing download sizes significantly.


# Generate App Bundle
flutter build appbundle --release

# Output location
# build/app/outputs/bundle/release/app-release.aab
                                    

Output:

✓ Built build/app/outputs/bundle/release/app-release.aab (15.2MB)

AAB vs APK

📉

Smaller Downloads

App Bundles enable Google Play to generate device-specific APKs, reducing download size by up to 35% compared to universal APKs by excluding unused resources.

# AAB: 15MB → APK: 10MB (per device)
🎯

Dynamic Delivery

Google Play uses AAB to deliver only the code and resources needed for each device's screen density, CPU architecture, and language, optimizing user experience.

# Only arm64 + hdpi + en delivered

Play Store Required

AAB is the required format for new apps on Google Play Store since August 2021. It cannot be installed directly on devices like APK files.

# Upload to Play Console only
🔐

App Signing

Google Play manages app signing with AAB through Play App Signing, providing additional security and allowing you to update your signing key if needed.

# Google signs final APKs

🔹 Building an App Bundle

Generate a release App Bundle for Google Play:

# Step 1: Clean project
flutter clean

# Step 2: Get dependencies
flutter pub get

# Step 3: Build App Bundle
flutter build appbundle --release

# Output location
# build/app/outputs/bundle/release/app-release.aab

Build Output:

Running Gradle task 'bundleRelease'...
✓ Built build/app/outputs/bundle/release/app-release.aab (15.2MB)

🔹 Configure App Signing

Set up signing configuration in android/app/build.gradle:

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    ...
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword keystoreProperties['storePassword']
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

🔹 Play App Signing Setup

Enable Play App Signing in Google Play Console:

Steps to Enable:

  1. Go to Google Play Console
  2. Select your app
  3. Navigate to Release → Setup → App Signing
  4. Choose "Use Google-generated key" or upload your own
  5. Download the upload certificate
  6. Use upload key to sign your AAB
# Google manages the final signing key
# You sign with upload key
# Google re-signs with app signing key

🔹 Testing App Bundle Locally

Test AAB using bundletool before uploading:

# Download bundletool
# https://github.com/google/bundletool/releases

# Generate APKs from AAB
java -jar bundletool.jar build-apks \
  --bundle=app-release.aab \
  --output=app.apks \
  --ks=my-release-key.jks \
  --ks-key-alias=my-key-alias

# Install on connected device
java -jar bundletool.jar install-apks --apks=app.apks

# Get device-specific APK size
java -jar bundletool.jar get-size total \
  --apks=app.apks

🔹 Upload to Play Console

Upload your App Bundle to Google Play Console:

Upload Steps:

  1. Open Google Play Console
  2. Select your app
  3. Go to Release → Production/Testing
  4. Create new release
  5. Upload app-release.aab
  6. Fill in release notes
  7. Review and rollout

🔹 AAB Optimization

Optimize your App Bundle for better performance:

# Build with obfuscation
flutter build appbundle --release \
  --obfuscate \
  --split-debug-info=./debug-info

# Analyze bundle size
flutter build appbundle --analyze-size

# Enable R8 full mode (android/gradle.properties)
android.enableR8.fullMode=true

Optimization Results:

Base AAB: 15.2MB

Optimized AAB: 12.8MB

Reduction: ~16%

🔹 Dynamic Feature Modules

Split your app into dynamic feature modules:

# pubspec.yaml
flutter:
  deferred-components:
    - name: feature_module
      libraries:
        - package:myapp/features/feature_module.dart
// Load feature dynamically
import 'features/feature_module.dart' deferred as feature;

Future loadFeature() async {
  await feature.loadLibrary();
  feature.showFeature();
}

🔹 Common AAB Issues

Troubleshoot common App Bundle problems:

Issue: Upload Key Mismatch

Solution: Ensure you're using the correct upload certificate from Play Console

Issue: Missing Signing Config

Solution: Verify key.properties file exists and build.gradle is configured correctly

Issue: AAB Too Large

Solution: Enable obfuscation, remove unused resources, optimize images

🧠 Test Your Knowledge

What is the main advantage of AAB over APK?