Android App Bundle (AAB) Complete Guide

Learn how to create, configure, and deploy Android App Bundles for optimized app distribution. This comprehensive guide covers everything from basic setup to advanced deployment strategies.

What is an Android App Bundle?

Android App Bundle (AAB) is Android's recommended publishing format that includes all your app's compiled code and resources, and defers APK generation and signing to Google Play.

Key Features

  • Smaller download sizes through dynamic delivery
  • Automatic APK optimization for different device configurations
  • Support for dynamic feature modules
  • Enhanced security with Play App Signing
💡 Pro Tip

Apps published with Android App Bundles are on average 15% smaller than traditional APKs.

Download Sample Project Download Configuration Templates

Prerequisites

Before creating your first Android App Bundle, ensure you have the following tools and knowledge.

Required Tools

  • Android Studio 3.2 or higher
  • Android Gradle Plugin 3.2.0 or higher
  • Gradle 4.9 or higher
  • Java 8 or higher
Gradle
// Check your current versions
android {
    compileSdkVersion 34
    buildToolsVersion "34.0.0"
    
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 34
    }
}
⚠️ Important

Make sure your app targets API level 31 (Android 12) or higher for new app submissions to Google Play.

AAB Benefits

Understanding the advantages of Android App Bundles over traditional APK distribution.

Size Optimization

AABs enable Google Play to generate optimized APKs for each device configuration, reducing download sizes by up to 35%.

Comparison
Traditional APK: 50MB (includes all resources)
AAB Generated APK: 32MB (device-specific resources only)
Savings: 36% smaller download

Dynamic Delivery

Deliver features on-demand, reducing initial install size and improving user experience.

💡 Use Cases for Dynamic Features
  • Camera filters for photo apps
  • Advanced editing tools
  • Premium features
  • Language packs

Gradle Setup

Configure your project's Gradle files to support Android App Bundle generation.

Project-level build.gradle

Gradle
buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:8.2.0'
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

App-level build.gradle

Gradle
android {
    compileSdk 34
    
    defaultConfig {
        applicationId "com.example.myapp"
        minSdk 21
        targetSdk 34
        versionCode 1
        versionName "1.0"
    }
    
    bundle {
        language {
            enableSplit = true
        }
        density {
            enableSplit = true
        }
        abi {
            enableSplit = true
        }
    }
    
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
Configuration Splits Explained
  • Language: Separate APKs for different languages
  • Density: Separate APKs for different screen densities
  • ABI: Separate APKs for different CPU architectures

Build Configuration

Advanced build configurations for optimizing your Android App Bundle.

Building the Bundle

Terminal
# Build debug bundle
./gradlew bundleDebug

# Build release bundle
./gradlew bundleRelease

# Build specific variant
./gradlew bundleProductionRelease

Advanced Bundle Configuration

Gradle
android {
    bundle {
        language {
            enableSplit = true
        }
        density {
            enableSplit = true
        }
        abi {
            enableSplit = true
        }
        
        // Disable splits for specific configurations
        storeArchive {
            enable = false
        }
    }
    
    // Optimize for size
    packagingOptions {
        resources {
            excludes += ['META-INF/DEPENDENCIES']
            excludes += ['META-INF/LICENSE']
            excludes += ['META-INF/LICENSE.txt']
            excludes += ['META-INF/NOTICE']
            excludes += ['META-INF/NOTICE.txt']
        }
    }
}
⚠️ Testing Considerations

Always test your app with the generated APKs from your bundle to ensure all splits work correctly on target devices.

Dynamic Features

Implement dynamic feature modules for on-demand delivery and reduced initial app size.

Creating a Dynamic Feature Module

Gradle
// In dynamic feature module's build.gradle
plugins {
    id 'com.android.dynamic-feature'
}

android {
    compileSdk 34
    
    defaultConfig {
        minSdk 21
    }
}

dependencies {
    implementation project(':app')
}

App Module Configuration

Gradle
// In app module's build.gradle
android {
    dynamicFeatures = [':dynamic_feature_camera', ':dynamic_feature_premium']
}

Loading Dynamic Features

Kotlin
// Install dynamic feature
val splitInstallManager = SplitInstallManagerFactory.create(context)
val request = SplitInstallRequest.newBuilder()
    .addModule("dynamic_feature_camera")
    .build()

splitInstallManager.startInstall(request)
    .addOnSuccessListener { sessionId ->
        // Handle successful installation
    }
    .addOnFailureListener { exception ->
        // Handle installation failure
    }
💡 Best Practices
  • Keep dynamic features under 10MB for optimal user experience
  • Provide fallback functionality when features aren't available
  • Use conditional delivery for region-specific features

App Signing

Configure app signing for your Android App Bundle with Play App Signing.

Signing Configuration

Gradle
android {
    signingConfigs {
        release {
            storeFile file('path/to/keystore.jks')
            storePassword 'store_password'
            keyAlias 'key_alias'
            keyPassword 'key_password'
        }
    }
    
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
⚠️ Security Warning

Never commit signing credentials to version control. Use environment variables or gradle.properties (excluded from VCS).

Environment Variables Approach

Gradle
android {
    signingConfigs {
        release {
            storeFile file(System.getenv("KEYSTORE_PATH") ?: "keystore.jks")
            storePassword System.getenv("KEYSTORE_PASSWORD")
            keyAlias System.getenv("KEY_ALIAS")
            keyPassword System.getenv("KEY_PASSWORD")
        }
    }
}

Upload Key Setup

Set up your upload key for Google Play App Signing and secure key management.

Generate Upload Key

Terminal
keytool -genkey -v -keystore upload-keystore.jks \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -alias upload -storetype JKS
Play App Signing Benefits
  • Google manages your app signing key securely
  • Ability to reset upload key if compromised
  • Enhanced security with Google's infrastructure
  • Automatic optimization for different devices

Export Certificate for Play Console

Terminal
keytool -export -rfc -keystore upload-keystore.jks \
  -alias upload -file upload_certificate.pem

Security Best Practices

Essential security practices for Android App Bundle development and distribution.

Code Obfuscation

Gradle
android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

ProGuard Rules

ProGuard
# Keep application class
-keep public class * extends android.app.Application

# Keep all model classes
-keep class com.example.myapp.model.** { *; }

# Keep Retrofit interfaces
-keep interface com.example.myapp.api.** { *; }

# Remove logging in release
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}
⚠️ Security Checklist
  • Enable code obfuscation for release builds
  • Remove debug logs and sensitive information
  • Use HTTPS for all network communications
  • Implement certificate pinning
  • Validate all user inputs
  • Store sensitive data securely (Android Keystore)

Local Testing

Test your Android App Bundle locally before uploading to Google Play Console.

Using bundletool

Terminal
# Download bundletool
wget https://github.com/google/bundletool/releases/latest/download/bundletool-all-1.15.4.jar

# Generate APKs from bundle
java -jar bundletool-all-1.15.4.jar build-apks \
  --bundle=app-release.aab \
  --output=app-release.apks \
  --ks=upload-keystore.jks \
  --ks-pass=pass:your_keystore_password \
  --ks-key-alias=upload \
  --key-pass=pass:your_key_password

Install APKs for Testing

Terminal
# Install APKs on connected device
java -jar bundletool-all-1.15.4.jar install-apks \
  --apks=app-release.apks

# Install specific device configuration
java -jar bundletool-all-1.15.4.jar install-apks \
  --apks=app-release.apks \
  --device-id=device_serial_number

Analyze Bundle Size

Terminal
# Get size information
java -jar bundletool-all-1.15.4.jar get-size total \
  --aab=app-release.aab

# Get device-specific size
java -jar bundletool-all-1.15.4.jar get-size total \
  --aab=app-release.aab \
  --device-spec=device_spec.json
💡 Testing Tips
  • Test on multiple device configurations
  • Verify dynamic features install correctly
  • Check app size on different devices
  • Test offline functionality

Play Console Upload

Upload your Android App Bundle to Google Play Console and configure distribution settings.

Upload Process

  1. Sign in to Google Play Console
  2. Select your app or create a new one
  3. Navigate to Release > Production
  4. Click "Create new release"
  5. Upload your .aab file
  6. Fill in release notes
  7. Review and roll out
Release Tracks
  • Internal testing: Up to 100 testers, immediate availability
  • Closed testing: Up to 20,000 testers, opt-in required
  • Open testing: Anyone can join, public on Play Store
  • Production: Live release to all users

Automated Upload with Gradle

Gradle
plugins {
    id 'com.github.triplet.play' version '3.8.4'
}

play {
    serviceAccountCredentials = file('service-account.json')
    track = 'internal'
    releaseStatus = 'completed'
    
    // Upload bundle instead of APK
    artifactDir = file('build/outputs/bundle/release')
}
⚠️ First Upload Requirements

For first-time uploads, you must manually upload through the Play Console web interface. Automated uploads work for subsequent releases.

Download Service Account Setup Guide

Monitoring & Analytics

Monitor your app's performance and analyze user behavior after AAB deployment.

Play Console Analytics

  • Download size by device configuration
  • Install success rates
  • Dynamic feature adoption
  • Crash reports and ANRs
  • User acquisition metrics

Firebase Analytics Integration

Gradle
dependencies {
    implementation 'com.google.firebase:firebase-analytics:21.5.0'
    implementation 'com.google.firebase:firebase-crashlytics:18.6.0'
}

Track Dynamic Feature Usage

Kotlin
// Track dynamic feature installation
FirebaseAnalytics.getInstance(this).logEvent("dynamic_feature_install") {
    param("feature_name", "camera_filters")
    param("install_success", true)
    param("install_time_ms", installTimeMs)
}
💡 Key Metrics to Monitor
  • App size reduction percentage
  • Install conversion rates
  • Dynamic feature adoption rates
  • Crash-free user percentage
  • App startup time
🎉 Congratulations!

You've completed the Android App Bundle guide! Your app is now optimized for modern Android distribution with smaller download sizes and better user experience.