I have a published app written in Kotlin which uses the Coroutines library, used primarily together with Retrofit2 for API requests. I am using another library, Kotlin Coroutines for Retrofit, which ties Coroutines and Retrofit2 together.
In my latest build, with the intent of reducing the APK size, I set minifyEnabled true
and added ProGuard rules as instructed by the libraries I use.
The problem:
The Google Play Console is informing me about crashes on the following devices: BQ Aquaris U Plus, Samsung Galaxy Grand Neo Plus, RCA 7 Voyager. The app works properly on most devices.
The stack trace:
java.lang.RuntimeException:
at kotlinx.coroutines.experimental.DispatchTask.run (CoroutineDispatcher.kt:127)
at android.os.Handler.handleCallback (Handler.java:751)
at android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop (Looper.java:154)
at android.app.ActivityThread.main (ActivityThread.java:6119)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:776)
Caused by: java.util.ServiceConfigurationError:
at java.util.ServiceLoader.fail (ServiceLoader.java:225)
at java.util.ServiceLoader.-wrap1 (ServiceLoader.java)
at java.util.ServiceLoader$LazyIterator.next (ServiceLoader.java:366)
at java.util.ServiceLoader$1.next (ServiceLoader.java:448)
at kotlinx.coroutines.experimental.CoroutineExceptionHandlerKt.handleCoroutineException (CoroutineExceptionHandler.kt:97)
at kotlinx.coroutines.experimental.StandaloneCoroutine.onCancellation (Builders.kt:176)
at kotlinx.coroutines.experimental.JobSupport.completeUpdateState$kotlinx_coroutines_core (Job.kt:730)
at kotlinx.coroutines.experimental.JobSupport.updateState$kotlinx_coroutines_core (Job.kt:671)
at kotlinx.coroutines.experimental.JobSupport.makeCompleting$kotlinx_coroutines_core (Job.kt:1040)
at kotlinx.coroutines.experimental.AbstractCoroutine.resumeWithException (AbstractCoroutine.kt:51)
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume (CoroutineImpl.kt:53)
at kotlinx.coroutines.experimental.DispatchTask.run (CoroutineDispatcher.kt:123)
Caused by: java.lang.ClassNotFoundException:
at java.lang.Class.classForName (Native Method)
at java.lang.Class.forName (Class.java:400)
at java.util.ServiceLoader$LazyIterator.next (ServiceLoader.java:364)
Caused by: java.lang.ClassNotFoundException:
at dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass (ClassLoader.java:380)
at java.lang.ClassLoader.loadClass (ClassLoader.java:312)
My app/build.gradle
file:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'realm-android'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "il.ronmad.speedruntimer"
minSdkVersion 19
targetSdkVersion 27
versionCode 26
versionName '3.1'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
testOptions {
unitTests.returnDefaultValues = true
}
productFlavors {
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
test.java.srcDirs += "src/test/kotlin"
androidTest.java.srcDirs += 'src/androidTest/kotlin'
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support:design:27.0.2'
implementation 'com.android.support:support-v4:27.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'com.jaredrummler:colorpicker:1.0.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.20'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.8.2'
implementation 'com.google.guava:guava:23.6-android'
testImplementation 'junit:junit:4.12'
testImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
androidTestImplementation 'com.android.support:support-annotations:27.0.2'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test:rules:1.0.1'
}
repositories {
jcenter()
}
My proguard-rules.pro
file:
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
-dontobfuscate
-dontoptimize
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-keep class il.ronmad.speedruntimer.** { *; }
# Gson
-dontwarn sun.misc.**
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Coroutines
-dontwarn org.jetbrains.kotlinx.**
-keepclassmembernames class kotlinx.** {
volatile <fields>;
}
# Retrofit
-dontnote retrofit2.Platform
-dontwarn retrofit2.Platform$Java8
-dontwarn okio.**
-dontwarn retrofit2.**
-dontwarn javax.annotation.**
# Guava
-dontwarn com.google.**
-dontwarn javax.inject.**
-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
-dontwarn java.lang.ClassValue
-dontwarn com.google.j2objc.annotations.Weak
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn afu.org.checkerframework.**
-dontwarn org.checkerframework.**
-keep class com.google.common.collect.Lists {
public static ** cartesianProduct(**);
}
I tried adding the following ProGuard rules, to no avail:
-keep class org.jetbrains.kotlinx.**
-keep class ru.gildor.coroutines.**
Any help would be appreciated. Thank you
Please add the below Proguard rules that will make it work in the release mode.
-keepclassmembernames class kotlinx.** {
volatile <fields>;
}
Reference is taken from the Kotline Co-routine
Edit: Tried above reference didn't work
Correct solution for now is below
-keepnames class kotlinx.** { *; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With