Home > Blockchain >  Release apk throws a fatal exception whereas debug does not
Release apk throws a fatal exception whereas debug does not

Time:02-11

I have implemented an SDK to the Android module of my Flutter project. In debug, I have gotten everything functioning as expected, but when I build a release APK and install it, everything functions as expected until I initialize a class from the SDK.

  • I've upgraded Kotlin, Gradle, Android Gradle Plugin, NDK, Flutter, and Dart
  • I've tried invalidating the project cache
  • I've tried flutter clean. Flutter doctor says there are no issues.
  • I've tried building with minify set to false.
  • I don't have any discrepancies between gradle buildTypes apart from signing the release.

I think proguard might be an issue causing the SDK to be stripped down seeing as it works in debug and not release. I have been stumped by this for about two weeks now and it seems that no amount of my research is acceptable or salutary. Is there anything that I may be missing that could cause an SDK to be stripped down like this on a release build?

EDIT:
Here is my AAPT_rules.txt

-keep class androidx.core.app.CoreComponentFactory { <init>(); }

**HERE IS THE SDK**
-keep class com.thisIsTheSDK.AlertActivity { <init>(); }
-keep class com.thisIsTheSDK.DashboardActivity { <init>(); }
-keep class com.thisIsTheSDK.RecallActivity { <init>(); }
-keep class com.thisIsTheSDK.WebFrameActivity { <init>(); }
**THAT WAS IT**

-keep class com.google.android.datatransport.runtime.backends.TransportBackendDiscovery { <init>(); }
-keep class com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver { <init>(); }
-keep class com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService { <init>(); }
-keep class com.google.android.gms.common.api.GoogleApiActivity { <init>(); }
-keep class com.google.android.gms.measurement.AppMeasurementJobService { <init>(); }
-keep class com.google.android.gms.measurement.AppMeasurementReceiver { <init>(); }
-keep class com.google.android.gms.measurement.AppMeasurementService { <init>(); }
-keep class com.google.firebase.components.ComponentDiscoveryService { <init>(); }
-keep class com.google.firebase.provider.FirebaseInitProvider { <init>(); }
-keep class com.MYPROJECT.MainActivity { <init>(); }
-keep class io.flutter.plugins.urllauncher.WebViewActivity { <init>(); }
-keep class android.widget.Space { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.app.AlertController$RecycleListView { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.view.menu.ActionMenuItemView { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.view.menu.ExpandedMenuView { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.view.menu.ListMenuItemView { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.ActionBarContainer { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.ActionBarContextView { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.ActionBarOverlayLayout { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.ActionMenuView { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.ActivityChooserView$InnerLayout { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.AlertDialogLayout { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.ButtonBarLayout { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.ContentFrameLayout { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.DialogTitle { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.FitWindowsFrameLayout { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.FitWindowsLinearLayout { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.SearchView$SearchAutoComplete { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.Toolbar { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.appcompat.widget.ViewStubCompat { <init>(android.content.Context, android.util.AttributeSet); }

-keep class androidx.core.widget.NestedScrollView { <init>(android.content.Context, android.util.AttributeSet); }

I did try removing the -keep class command and replace it with

-keep class com.thisIsTheSDK.** { *; }

but after building, that didn't seem to change the outcome and then it reverted to the previous commands.

CodePudding user response:

So it turns out the AAPT_rules.txt is an automatic rule set. I couldn't find how or why, but it appears that Flutter was building with minify or shrink turned on. I tried adding rules to the AAPT_rules but they kept getting overwritten. The solution for me was setting the default proguard file, building to generate the proguard file, adding rules to keep all classes in the SDK, and then rebuilding.

Here's how I set the default proguard file. In the app level build.gradle, I added this:

android {
    buildTypes {
        release {
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

And then in the generated proguard-rules.pro, I added this rule:

-keep class com.thisIsTheSDK.** { *; }
  • Related