From 7d421c1d8b513c3844d69fab3bb6f79254ccbdc9 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Thu, 25 Jun 2026 17:34:15 +0200 Subject: [PATCH] Add R8 keep rules and re-enable release minification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit disabled isMinifyEnabled/isShrinkResources as a crash workaround (AGP 9 default minification stripped WorkDatabase_Impl's no-arg constructor). This commit adds the proper fix: - new android/app/proguard-rules.pro: keeps the no-arg constructor on all RoomDatabase subclasses (the gap the Room AAR's own consumer rule misses — it keeps the class name but not the reflectively-called constructor), plus WorkManager worker/InputMerger rules re-stated from the work-runtime AAR in case transitive consumer-rule propagation is incomplete through the Flutter plugin wrapper. - build.gradle.kts: re-enables isMinifyEnabled=true + isShrinkResources=true with proguard-android-optimize.txt + proguard-rules.pro. Verified on the real phone (BL9000): minified release APK launches without crash, MainActivity foreground, food-bank suggestions and slot chips render correctly. APK size 52.1 MB (vs 56.9 MB unminified). Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01SWPUBzE24Ls9i9GMRwXnnn --- app/android/app/build.gradle.kts | 14 ++++++-------- app/android/app/proguard-rules.pro | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 app/android/app/proguard-rules.pro diff --git a/app/android/app/build.gradle.kts b/app/android/app/build.gradle.kts index 8ab020a..99094b5 100644 --- a/app/android/app/build.gradle.kts +++ b/app/android/app/build.gradle.kts @@ -33,14 +33,12 @@ android { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig = signingConfigs.getByName("debug") - // AGP 9 defaults release minification (and resource shrinking, - // which requires it) to true. R8 then strips - // WorkDatabase_Impl's reflection-only no-arg constructor (no - // keep rule covers it), crashing every release launch with - // NoSuchMethodException. Disable both until proper - // Room/WorkManager keep rules are added. - isMinifyEnabled = false - isShrinkResources = false + isMinifyEnabled = true + isShrinkResources = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro", + ) } } } diff --git a/app/android/app/proguard-rules.pro b/app/android/app/proguard-rules.pro new file mode 100644 index 0000000..574157c --- /dev/null +++ b/app/android/app/proguard-rules.pro @@ -0,0 +1,20 @@ +# Room: keep generated *_Impl classes and their no-arg constructors. +# The Room AAR ships "-keep class * extends RoomDatabase" but that only +# protects the class from removal/renaming — R8 still strips the no-arg +# constructor because it's only ever called via Class.getDeclaredConstructors() +# (reflection inside RoomDatabase.create()), which R8 cannot trace statically. +-keep class * extends androidx.room.RoomDatabase { (); } +-dontwarn androidx.room.paging.** +-dontwarn androidx.lifecycle.LiveData + +# WorkManager: keep worker classes, their two-arg constructors, and the +# WorkerParameters type passed to them. Sourced from work-runtime AAR's +# own proguard.txt — re-stated here so they apply even if transitive +# consumer-rule propagation through the Flutter plugin wrapper is incomplete. +-keepnames class * extends androidx.work.ListenableWorker +-keepclassmembers public class * extends androidx.work.ListenableWorker { + public (...); +} +-keep class androidx.work.WorkerParameters +-keepnames class * extends androidx.work.InputMerger +-keepclassmembers class * extends androidx.work.InputMerger { void (); }