问题
Expected
It is expected for the release version of the Android app's build to run successfully when enabling minifyEnabled
and shrinkResources
per the Android documentation, Crashlytics, and Proguard.
The code for this issue may be found in the open-sourced GitHub repository for Coinverse.
Observed
The release version of the app crashes immediately when opened after being downloaded from Google Play. This appears to be due to Crashlytics failing to initialize.
Without
minifyEnabled
andshrinkResources
the app runs as expected in production, and the app size goes from ~4mb to ~10mb.The error log suggests it is an issue with Firebase compatibility and recommends this StackOverflow post. - What ProGuard configuration do I need for Firebase on Android?
There is a similar issue with ProGuard - transformClassesAndResourcesWithProguardForRelease FAILED.
Error
Summary
Crashlytics Core: Failed to execute task
Details
2020-04-13 22:57:04.750 25234-25234/? E/app.coinverse: Unknown bits set in runtime_flags: 0x8000
2020-04-13 22:57:06.310 25234-25234/app.coinverse E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.coinverse, PID: 25234
java.lang.RuntimeException: Unable to create application app.coinverse.App: java.lang.RuntimeException: Failed to instantiate AndroidPlatform class. Using ProGuard? See http://stackoverflow.com/questions/26273929/what-proguard-configuration-do-i-need-for-firebase-on-android
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6465)
at android.app.ActivityThread.access$1300(ActivityThread.java:219)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.RuntimeException: Failed to instantiate AndroidPlatform class. Using ProGuard? See http://stackoverflow.com/questions/26273929/what-proguard-configuration-do-i-need-for-firebase-on-android
at e.e.a.d.a.a(:69)
at e.e.a.a.a(:974)
at d.a.k.a.<init>(:42)
at d.a.k.b.a(:29)
at d.a.k.b.get(:21)
at d.a.k.b.get(:8)
at f.b.b.get(:47)
at d.a.i.d.a(:107)
at app.coinverse.App.onCreate(:18)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1189)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6460)
at android.app.ActivityThread.access$1300(ActivityThread.java:219)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.NoSuchMethodException: e.e.a.c.a.<init> [class android.content.Context]
at java.lang.Class.getConstructor0(Class.java:2332)
at java.lang.Class.getConstructor(Class.java:1728)
at e.e.a.d.a.a(:62)
at e.e.a.a.a(:974)
at d.a.k.a.<init>(:42)
at d.a.k.b.a(:29)
at d.a.k.b.get(:21)
at d.a.k.b.get(:8)
at f.b.b.get(:47)
at d.a.i.d.a(:107)
at app.coinverse.App.onCreate(:18)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1189)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6460)
at android.app.ActivityThread.access$1300(ActivityThread.java:219)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2020-04-13 22:57:10.312 25234-25234/app.coinverse E/CrashlyticsCore: Failed to execute task.
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:206)
at e.b.a.e.u.b(:41)
at e.b.a.e.k1.a(:321)
at e.b.a.e.t0.a(:301)
at e.b.a.e.y1.uncaughtException(:42)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1073)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
at java.lang.Thread.dispatchUncaughtException(Thread.java:2187)
Implementation
build.gradle (:app)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'io.fabric'
apply plugin: 'de.mannodermaus.android-junit5'
android {
compileSdkVersion 29
defaultConfig {
applicationId "app.coinverse"
minSdkVersion 24
targetSdkVersion 29
versionCode 57
versionName "0.57"
kotlinOptions { jvmTarget = '1.8' }
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
sourceSets { androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) }
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro',
'proguard.cfg'
}
debug {
applicationIdSuffix ".staging"
debuggable true
}
open {
initWith debug
applicationIdSuffix ".open"
}
}
compileOptions { targetCompatibility JavaVersion.VERSION_1_8 }
dataBinding.enabled = true
testOptions { unitTests.includeAndroidResources = true }
}
dependencies {
def lifecycle_version = '2.2.0'
def lifecycle_test_version = '2.1.0'
def nav_version = '2.2.1'
def play_services_version = '17.0.0'
def exoplayer_version = '2.11.1'
def room_version = '2.2.5'
def glide_version = '4.11.0'
def mopub_version = '5.12.0'
def junit_version = '5.5.1'
def test_rules_core_version = '1.2.0'
def fragment_version = '1.2.4'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.dagger:dagger:2.27'
kapt 'com.google.dagger:dagger-compiler:2.27'
implementation "androidx.fragment:fragment-ktx:$fragment_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
implementation "androidx.paging:paging-runtime-ktx:2.1.2"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1'
implementation "com.google.android.gms:play-services-auth:18.0.0"
implementation "com.google.android.gms:play-services-location:$play_services_version"
implementation 'com.firebase:firebase-client-android:2.5.2'
implementation 'com.google.firebase:firebase-analytics:17.3.0'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
implementation 'com.google.firebase:firebase-perf:19.0.5'
implementation 'com.google.firebase:firebase-firestore-ktx:21.4.0'
implementation 'com.google.firebase:firebase-functions:19.0.2'
implementation 'com.google.firebase:firebase-auth:19.3.0'
implementation 'com.firebaseui:firebase-ui-firestore:4.2.0'
implementation 'com.firebaseui:firebase-ui-auth:4.2.1'
implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'com.google.firebase:firebase-inappmessaging-display:19.0.4'
implementation 'com.google.firebase:firebase-config:19.1.3'
implementation 'com.jjoe64:graphview:4.2.2'
implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version"
implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayer_version"
implementation files('libs/YouTubeAndroidPlayerApi.jar')
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
implementation "com.github.bumptech.glide:glide:$glide_version"
kapt "com.github.bumptech.glide:compiler:$glide_version"
implementation("com.mopub:mopub-sdk-native-static:$mopub_version") { transitive = true }
implementation("com.mopub:mopub-sdk-native-video:$mopub_version") { transitive = true }
implementation 'com.facebook.android:audience-network-sdk:5.8.0'
implementation 'com.mopub.mediation:facebookaudiencenetwork:5.8.0.0'
implementation 'com.flurry.android:ads:12.3.0'
implementation 'com.flurry.android:analytics:12.3.0'
implementation 'com.mopub.mediation:flurry:12.0.3.1'
// Testing
// Local Unit
testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_version"
testImplementation "org.junit.jupiter:junit-jupiter-params:$junit_version"
testImplementation "io.mockk:mockk:1.9.3"
testImplementation 'org.assertj:assertj-core:3.13.2'
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
testImplementation "androidx.arch.core:core-testing:$lifecycle_test_version"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2"
// AndroidX - JVM
testImplementation "androidx.test:core-ktx:1.2.0"
testImplementation "androidx.test.ext:junit-ktx:1.1.1"
testImplementation "androidx.test:rules:$test_rules_core_version"
testImplementation "androidx.test:core:$test_rules_core_version"
}
build.gradle (android)
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.71'
repositories {
google()
jcenter()
mavenCentral()
maven { url 'https://maven.google.com' }
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:perf-plugin:1.3.1'
classpath 'io.fabric.tools:gradle:1.31.2'
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
classpath "de.mannodermaus.gradle.plugins:android-junit5:1.5.1.0"
}
}
allprojects {
repositories {
google()
jcenter()
maven { url 'https://maven.google.com/' }
maven { url "https://s3.amazonaws.com/moat-sdk-builds" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
App.kt
The release version of the app is crashing when attempting to initialize the FirebaseHelper.kt class.
class App : Application() {
val component = DaggerComponent.builder()
.utilsModule(UtilsModule(this))
.build()
override fun onCreate() {
super.onCreate()
// Here is where the crash occurs.
component.firebaseHelper()
MoPub.initializeSdk(this, SdkConfiguration.Builder(AD_UNIT_ID).build(), initSdkListener())
}
private fun initSdkListener() = SdkInitializationListener { /* MoPub SDK initialized.*/ }
}
FirebaseHelper.kt
@Singleton
class FirebaseHelper @Inject constructor(context: Context) {
private val LOG_TAG = FirebaseHelper::class.java.simpleName
init {
if (BuildConfig.BUILD_TYPE == open.name) {
var openSharedStatus = false
FirebaseApp.getApps(context).map { app ->
if (app.name.equals(open.name))
openSharedStatus = true
}
if (!openSharedStatus)
FirebaseApp.initializeApp(
context,
FirebaseOptions.Builder()
.setApplicationId(APP_ID_OPEN_SHARED)
.setApiKey(APP_API_KEY_OPEN_SHARED)
.setDatabaseUrl(DATABASE_URL_OPEN_SHARED)
.setProjectId(PROJECT_ID_OPEN_SHARED)
.setStorageBucket(STORAGE_BUCKET_OPEN_SHARED)
.build(),
open.name)
}
Firebase.setAndroidContext(context)
initializeRemoteConfig()
}
private fun initializeRemoteConfig() {
val firebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
firebaseRemoteConfig.setConfigSettingsAsync(FirebaseRemoteConfigSettings.Builder().build())
firebaseRemoteConfig.setDefaultsAsync(R.xml.remote_config_defaults)
val cacheExpiration = 3600L
try {
firebaseRemoteConfig.fetch(cacheExpiration)
firebaseRemoteConfig.fetchAndActivate()
} catch (exception: FirebaseRemoteConfigException) {
Crashlytics.log(Log.ERROR, LOG_TAG, "initializeRemoteConfig: ${exception.localizedMessage}")
}
}
}
Attempted Solutions
1 - Explicitly enabling Crashlytics in build.gradle
buildTypes {
release {
ext.enableCrashlytics = true
...
}
...
}
2 - Adding proguard.cfg rules for Firebase.
-keep class com.firebase.** { *; }
-keep class org.apache.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.w3c.dom.**
-dontwarn org.joda.time.**
-dontwarn org.shaded.apache.**
-dontwarn org.ietf.jgss.**
# Only necessary if you downloaded the SDK jar directly instead of from maven.
-keep class com.shaded.fasterxml.jackson.** { *; }
3 - Adding proguard.cfg rules for the app model classes being returned and posted to Firestore's database.
# Add this global rule
-keepattributes Signature
-keepclassmembers class app.coinverse.analytics.models.** {
*;
}
-keepclassmembers class app.coinverse.feed.models.** {
*;
}
-keepclassmembers class app.coinverse.priceGraph.models.** {
*;
}
-keepclassmembers class app.coinverse.user.models.** {
*;
}
-keepclassmembers class app.coinverse.utils.** {
*;
}
4 - Adding pro-guard-rules-release.txt
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-release.txt'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-test.txt'
来源:https://stackoverflow.com/questions/57010884/crash-with-proguard-and-firebase-crashlytics