From 5e3cbf241924ca99b5847fc6e8ffc532ce352b80 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Thu, 24 Sep 2026 20:59:17 +0200 Subject: [PATCH] fix: shrink the android release with r8 Release builds had R8 and resource shrinking off, so every class of every dependency went into the APK unminified: the published 0.1.62 is 42.8 MB for arm64, 25.85 MB of it dex (PF9 in the audit). Turn both on through the properties build.gradle already reads (`android.enableMinifyInReleaseBuilds` and `android.enableShrinkResourcesInReleaseBuilds`). The consumer rules of React Native, Expo, Firebase, ML Kit and the other libraries cover what they load by reflection. The app's own package is kept whole, which costs a few KB and keeps its frames readable in an obfuscated stack trace. Measured on a local x86_64 release build: - APK: 44.7 MB -> 38.0 MB (download size 23.8 MB -> 17.2 MB) - dex: 30.4 MB in 4 files -> 11.3 MB in 2 files - classes: 27,631 -> 16,724 With `-dontobfuscate` the APK would be 38.8 MB (13.5 MB of dex), so obfuscation stays on. Library frames in a release stack trace are now obfuscated; retrace them with that build's `android/app/build/outputs/mapping/release/mapping.txt`. Checked on the emulator: cold start in light and dark mode, German and Russian strings, SENDTO and VIEW mailto and SEND share intents, every sign-in screen, the QR scanner with ML Kit, and an FCM data message starting the headless push task. --- android/app/proguard-rules.pro | 9 +++++++++ android/gradle.properties | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index 551eb41d..88ba752b 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -12,3 +12,12 @@ -keep class com.facebook.react.turbomodule.** { *; } # Add any project specific keep options here: + +# The app's own native code (com.anonymous.bulwarkmobile). What R8 must not +# drop or rename there is already covered elsewhere: React Native's rules keep +# every NativeModule, whose @ReactMethod methods JS calls by name, and AAPT +# keeps the application, activity and services listed in AndroidManifest.xml +# (FCM, UnifiedPush and the headless JS task). Keeping the package whole on +# top of that costs a few KB and leaves its class and method names readable +# in a crash report from an obfuscated release build. +-keep class com.anonymous.bulwarkmobile.** { *; } diff --git a/android/gradle.properties b/android/gradle.properties index ad02561b..9d57fd03 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -25,6 +25,11 @@ android.useAndroidX=true # Enable AAPT2 PNG crunching android.enablePngCrunchInReleaseBuilds=true +# Shrink release builds with R8 (code) and the resource shrinker. Keep rules +# for classes reached by reflection go in app/proguard-rules.pro. +android.enableMinifyInReleaseBuilds=true +android.enableShrinkResourcesInReleaseBuilds=true + # Use this property to specify which architecture you want to build. # You can also override it from the CLI using # ./gradlew -PreactNativeArchitectures=x86_64