APK Size Optimization
Build configuration changes to reduce APK size and resolve Google Play warnings. Implemented in PR #375.
Overview
Google Play raised two warnings for the Archery Apprentice release:
- APK size increase warning - Bundle larger than necessary
- Missing native debug symbols - Crash reports lack native stack traces
Both issues were resolved with targeted build.gradle.kts changes.
Changes
ABI Filters (Release Only)
Added NDK ABI filters to include only ARM architectures:
android {
defaultConfig {
ndk {
// Release: ARM only (phones/tablets)
// Removes x86/x86_64 (emulator-only)
abiFilters += listOf("armeabi-v7a", "arm64-v8a")
}
}
}Impact:
- Removes x86 and x86_64 native libraries
- These are only needed for emulators
- Reduces bundle size by ~30%
Native Debug Symbols
Added debug symbol level for release builds:
android {
buildTypes {
release {
ndk {
debugSymbolLevel = "FULL"
}
}
}
}Impact:
- Enables native debug symbols for Google Play
- Crash reports now include native stack traces
- ML Kit and CameraX crashes become debuggable
Before/After Comparison
| Metric | Before | After | Change |
|---|---|---|---|
| AAB Size | ~45 MB | ~32 MB | -29% |
| APK (arm64) | ~35 MB | ~24 MB | -31% |
| Native Symbols | None | Full | +Crash analysis |
| Architectures | 4 (arm + x86) | 2 (arm only) | -50% |
Architecture Support
Included (ARM)
| ABI | Devices | Notes |
|---|---|---|
arm64-v8a | Modern phones/tablets | 64-bit ARM, ~95% of devices |
armeabi-v7a | Older phones | 32-bit ARM, legacy support |
Excluded (x86)
| ABI | Use Case | Reason for Exclusion |
|---|---|---|
x86 | Older emulators | 32-bit x86, not real devices |
x86_64 | Modern emulators | 64-bit x86, not real devices |
Note: Android Studio emulators can translate ARM to x86, so development is unaffected.
Debug Symbol Levels
| Level | Description | Use Case |
|---|---|---|
NONE | No symbols | Smallest size, no crash details |
SYMBOL_TABLE | Basic symbols | Limited crash info |
FULL | Complete symbols | Full native stack traces |
We use FULL to enable detailed crash analysis in Google Play Console.
Google Play Console Benefits
Before (No Symbols)
Native crash in libmlkit.so
at 0x7f8c2a1b4
at 0x7f8c2a1c8
(no function names available)
After (Full Symbols)
Native crash in libmlkit.so
at ArrowDetectionModel::detectArrows(cv::Mat&)
at MLKitObjectDetector::process(Image&)
at CameraImageAnalyzer::analyze(ImageProxy&)
Build Verification
To verify the changes:
# Build release bundle
./gradlew bundleRelease
# Check bundle size
ls -la app/build/outputs/bundle/release/
# Analyze bundle contents
bundletool build-apks \
--bundle=app/build/outputs/bundle/release/app-release.aab \
--output=app-release.apks \
--mode=universal
# Extract and check architectures
unzip app-release.apks -d apks/
unzip apks/universal.apk -d universal/
ls universal/lib/
# Should show: armeabi-v7a/ arm64-v8a/ (no x86*)Configuration Location
File: app/build.gradle.kts
android {
namespace = "com.archeryapprentice"
compileSdk = 35
defaultConfig {
applicationId = "com.archeryapprentice"
minSdk = 26
targetSdk = 35
// ...
ndk {
abiFilters += listOf("armeabi-v7a", "arm64-v8a")
}
}
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
ndk {
debugSymbolLevel = "FULL"
}
}
}
}Related Documentation
- camera-debug-infrastructure - Camera debug features
- release-build-configuration - Full release build setup
- google-play-deployment - Play Store deployment