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.
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
Apps published with Android App Bundles are on average 15% smaller than traditional APKs.
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
// Check your current versions
android {
compileSdkVersion 34
buildToolsVersion "34.0.0"
defaultConfig {
minSdkVersion 21
targetSdkVersion 34
}
}
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%.
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.
- 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
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.2.0'
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
App-level build.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'
}
}
}
- 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
# Build debug bundle
./gradlew bundleDebug
# Build release bundle
./gradlew bundleRelease
# Build specific variant
./gradlew bundleProductionRelease
Advanced Bundle Configuration
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']
}
}
}
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
// 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
// In app module's build.gradle
android {
dynamicFeatures = [':dynamic_feature_camera', ':dynamic_feature_premium']
}
Loading Dynamic Features
// 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
}
- 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
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'
}
}
}
Never commit signing credentials to version control. Use environment variables or gradle.properties (excluded from VCS).
Environment Variables Approach
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
keytool -genkey -v -keystore upload-keystore.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias upload -storetype JKS
- 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
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
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
ProGuard Rules
# 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(...);
}
- 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
# 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
# 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
# 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
- 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
- Sign in to Google Play Console
- Select your app or create a new one
- Navigate to Release > Production
- Click "Create new release"
- Upload your .aab file
- Fill in release notes
- Review and roll out
- 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
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')
}
For first-time uploads, you must manually upload through the Play Console web interface. Automated uploads work for subsequent releases.
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
dependencies {
implementation 'com.google.firebase:firebase-analytics:21.5.0'
implementation 'com.google.firebase:firebase-crashlytics:18.6.0'
}
Track Dynamic Feature Usage
// 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)
}
- App size reduction percentage
- Install conversion rates
- Dynamic feature adoption rates
- Crash-free user percentage
- App startup time
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.