Skip to content

Commit 1afcfd3

Browse files
richardthe3rdclaude
andcommitted
fix(android): add SourceFile/LineNumberTable attrs and tighten lifecycle dontwarn
- Add -keepattributes SourceFile,LineNumberTable so R8 preserves line numbers in the mapping file; without this crash stack traces show "Unknown Source" even after deobfuscation, defeating the PR's purpose - Remove redundant GeneratedPluginRegistrant keep rule (covered by the io.flutter.** wildcard) - Scope -dontwarn androidx.lifecycle.** to the specific optional interface (DefaultLifecycleObserver) rather than suppressing all lifecycle warnings - Update docs to document both Firebase Crashlytics and Play Console as mapping file destinations, and fix the retrace command to use the actual Android SDK path instead of a placeholder Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 725b3b5 commit 1afcfd3

2 files changed

Lines changed: 31 additions & 32 deletions

File tree

android/app/proguard-rules.pro

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
# Flutter wrapper classes (wildcard covers all io.flutter.** subpackages)
22
-keep class io.flutter.** { *; }
33

4-
# Preserve Flutter plugin registrant (auto-generated)
5-
-keep class io.flutter.plugins.GeneratedPluginRegistrant { *; }
6-
74
# Keep native methods
85
-keepclassmembers class * {
96
native <methods>;
107
}
118

12-
# Keep annotations used by Flutter plugins
9+
# Preserve source file names and line numbers so crash stack traces are actionable
10+
# (required by Firebase Crashlytics and Play Console for meaningful deobfuscation)
11+
-keepattributes SourceFile,LineNumberTable
1312
-keepattributes Signature
1413
-keepattributes *Annotation*
1514
-keepattributes InnerClasses
@@ -19,8 +18,11 @@
1918
# warnings for GMS classes that may be referenced but not included in all variants.
2019
-dontwarn com.google.android.gms.**
2120

22-
# Suppress warnings about missing optional classes
23-
-dontwarn androidx.lifecycle.**
21+
# Lifecycle interfaces are referenced by Firebase but resolved at runtime via the AAR;
22+
# suppress only the specific optional-observer interface, not all of androidx.lifecycle.
23+
-dontwarn androidx.lifecycle.DefaultLifecycleObserver
24+
25+
# Suppress warnings about missing optional TLS provider classes (used by OkHttp)
2426
-dontwarn org.conscrypt.**
2527
-dontwarn org.bouncycastle.**
2628
-dontwarn org.openjsse.**

docs/tooling/android-release.md

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,10 @@ storeFile=../../upload-keystore.jks
691691

692692
## Code Obfuscation & Optimization (ProGuard/R8)
693693

694-
Currently, ProGuard/R8 is **enabled** (`minifyEnabled = true`). This reduces app size and generates a deobfuscation mapping file that is automatically uploaded to Google Play Console, making crash analysis easier.
694+
Currently, ProGuard/R8 is **enabled** (`minifyEnabled = true`). This reduces app size and generates a deobfuscation mapping file that is uploaded to two destinations automatically:
695+
696+
- **Firebase Crashlytics** — uploaded during the Gradle build by the `firebase-crashlytics-gradle` plugin (`uploadCrashlyticsMappingFileRelease` task). Crash reports in the Firebase Console are deobfuscated automatically.
697+
- **Google Play Console** — uploaded by the CI release workflow (`release-android.yml`) after the AAB build. ANRs and crashes reported via Play Console are deobfuscated automatically.
695698

696699
### Why Enable ProGuard/R8?
697700

@@ -725,39 +728,26 @@ buildTypes {
725728
Create `android/app/proguard-rules.pro`:
726729

727730
```proguard
728-
# Flutter wrapper
729-
-keep class io.flutter.app.** { *; }
730-
-keep class io.flutter.plugin.** { *; }
731-
-keep class io.flutter.util.** { *; }
732-
-keep class io.flutter.view.** { *; }
733-
-keep class io.flutter.** { *; }
734-
-keep class io.flutter.plugins.** { *; }
735-
736-
# Preserve Flutter plugin registrant
737-
-keep class io.flutter.plugins.GeneratedPluginRegistrant { *; }
731+
# Flutter wrapper classes
732+
-keep class io.flutter.** { *; }
738733
739734
# Keep native methods
740735
-keepclassmembers class * {
741736
native <methods>;
742737
}
743738
744-
# Gson/JSON serialization (if using)
739+
# Preserve source file names and line numbers for actionable crash stack traces
740+
-keepattributes SourceFile,LineNumberTable
745741
-keepattributes Signature
746742
-keepattributes *Annotation*
747-
-keep class com.google.gson.** { *; }
748-
749-
# url_launcher
750-
-keep class io.flutter.plugins.urllauncher.** { *; }
751-
752-
# shared_preferences
753-
-keep class io.flutter.plugins.sharedpreferences.** { *; }
743+
-keepattributes InnerClasses
744+
-keepattributes EnclosingMethod
754745
755-
# cached_network_image
756-
-keep class com.example.cached_network_image.** { *; }
757-
758-
# Don't warn about missing classes
759746
-dontwarn com.google.android.gms.**
760-
-dontwarn androidx.lifecycle.**
747+
-dontwarn androidx.lifecycle.DefaultLifecycleObserver
748+
-dontwarn org.conscrypt.**
749+
-dontwarn org.bouncycastle.**
750+
-dontwarn org.openjsse.**
761751
```
762752

763753
**3. Test Thoroughly**
@@ -799,10 +789,17 @@ enabling automatic deobfuscation of crash stack traces in the Play Console.
799789
# Mapping file location (after a release build)
800790
build/app/outputs/mapping/release/mapping.txt
801791

802-
# Use retrace to deobfuscate a crash trace:
803-
java -jar /path/to/retrace.jar mapping.txt obfuscated_trace.txt
792+
# Deobfuscate using the Android SDK retrace tool:
793+
$ANDROID_HOME/tools/proguard/bin/retrace.sh -verbose mapping.txt obfuscated_trace.txt
794+
795+
# Or with a standalone retrace JAR:
796+
java -jar $ANDROID_HOME/tools/proguard/lib/retrace.jar -verbose mapping.txt obfuscated_trace.txt
804797
```
805798

799+
> **Note:** For AAB-based Play Store installs the mapping is also available in Play Console under
800+
> Android Vitals → Deobfuscation files. For sideloaded APK installs, save the mapping file from
801+
> CI artifacts within 7 days of the release build.
802+
806803
## Testing Before Release
807804

808805
### Test Unsigned APK

0 commit comments

Comments
 (0)