'Android generated signed APK crash with an error but it's work fine in debug mode
I have a code it's work fine in debug mode also generated signed APK will work fine if isMinifyEnabled=false but for generated signed APK when isMinifyEnabled=true generated apk file crash with this error:
java.lang.IllegalArgumentException: Class declares 0 type parameters, but 1 were provided.
at kotlin.reflect.jvm.internal.ReflectionFactoryImpl.typeOf(ReflectionFactoryImpl.java:28)
at kotlin.jvm.internal.Reflection.typeOf(Reflection.java:2)
at ir.namoo.commons.service.PrayTimesService.getAllCountries(PrayTimesService.kt:19)
at ir.namoo.commons.service.PrayTimesService$getAllCountries$1.invokeSuspend(Unknown Source:11)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:4)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:11)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:5)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:6)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:10)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:11)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:5)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:6)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:10)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:11)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:5)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:6)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:10)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:11)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:5)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:6)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:10)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:11)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:5)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:6)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:10)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:18)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
additional information
I use Android Studio Bumblebee | 2021.1.1 Patch 2 and latest library version and gradle 7.4.1
my progurd file
# remove Log calls from release builds
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** i(...);
}
-ignorewarnings
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-dontobfuscate
and this is getAllCountries function that exist in error log
class PrayTimesService @Inject constructor(private val httpClient: HttpClient) {
***
suspend fun getAllCountries(): List<CountryModel> {
val res =httpClient.get<ServerResponseModel<List<CountryModel>>>("$BASE_API_URL/getCountries")
return res.data
}
***
}
Solution 1:[1]
you need add proguard rules in proguard-rules.pro file every library(dependencies) like retrofit..etc using in project
Solution 2:[2]
If you're using ProGuard, you need to add rules to your proguard-rules.pro configuration to cover all classes that are serialized at runtime.
Add dependency on serialization runtime library:
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-serialization-json</artifactId>
<version>${serialization.version}</version>
</dependency>
The following configuration keeps serializers for all serializable classes that are retained after shrinking. Uncomment and modify the last section in case you're serializing classes with named companion objects.
# Keep `Companion` object fields of serializable classes.
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
-if @kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
static <1>$Companion Companion;
}
# Keep `serializer()` on companion objects (both default and named) of serializable classes.
-if @kotlinx.serialization.Serializable class ** {
static **$* *;
}
-keepclassmembers class <2>$<3> {
kotlinx.serialization.KSerializer serializer(...);
}
# Keep `INSTANCE.serializer()` of serializable objects.
-if @kotlinx.serialization.Serializable class ** {
public static ** INSTANCE;
}
-keepclassmembers class <1> {
public static <1> INSTANCE;
kotlinx.serialization.KSerializer serializer(...);
}
# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
# Serializer for classes with named companion objects are retrieved using `getDeclaredClasses`.
# If you have any, uncomment and replace classes with those containing named companion objects.
#-keepattributes InnerClasses # Needed for `getDeclaredClasses`.
#-if @kotlinx.serialization.Serializable class
#com.example.myapplication.HasNamedCompanion, # <-- List serializable classes with named companions.
#com.example.myapplication.HasNamedCompanion2
#{
# static **$* *;
#}
#-keepnames class <1>$$serializer { # -keepnames suffices; class is kept when serializer() is kept.
# static <1>$$serializer INSTANCE;
#}
In case you want to exclude serializable classes that are used, but never serialized at runtime, you will need to write custom rules with narrower class specifications.
Example of custom rules
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
# kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer
-keepclassmembers class kotlinx.serialization.json.** {
*** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
kotlinx.serialization.KSerializer serializer(...);
}
# Application rules
# Change here com.yourcompany.yourpackage
-keepclassmembers @kotlinx.serialization.Serializable class com.yourcompany.yourpackage.** {
# lookup for plugin generated serializable classes
*** Companion;
# lookup for serializable objects
*** INSTANCE;
kotlinx.serialization.KSerializer serializer(...);
}
# lookup for plugin generated serializable classes
-if @kotlinx.serialization.Serializable class com.yourcompany.yourpackage.**
-keepclassmembers class com.yourcompany.yourpackage.<1>$Companion {
kotlinx.serialization.KSerializer serializer(...);
}
# Serialization supports named companions but for such classes it is necessary to add an additional rule.
# This rule keeps serializer and serializable class from obfuscation. Therefore, it is recommended not to use wildcards in it, but to write rules for each such class.
-keepattributes InnerClasses # Needed for `getDeclaredClasses`.
-keep class com.yourcompany.yourpackage.SerializableClassWithNamedCompanion$$serializer {
*** INSTANCE;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | David Kariuki |