Android 生成签名的 APK 崩溃并出现错误,但在调试模式下工作正常

发布于 2025-01-15 15:49:40 字数 3976 浏览 3 评论 0原文

我有一个代码,它在调试模式下工作正常,并且生成的签名 APK 将工作正常,如果 isMinifyEnabled=false 但对于生成的签名 APK,当 isMinifyEnabled=true 生成的 apk 文件崩溃时会出现以下错误:

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)

附加信息

我使用 Android Studio Bumblebee | 2021.1.1 补丁 2 和最新的库版本和 gradle 7.4.1

我的 progurd 文件

# remove Log calls from release builds
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** i(...);
}

-ignorewarnings
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-dontobfuscate

,这是错误日志中存在的 getAllCountries 函数

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
    }
***
}

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
    }
***
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一笑百媚生 2025-01-22 15:49:40

您需要在 proguard-rules.pro 文件中的每个库(依赖项)中添加 proguard 规则,例如 Retrofit..etc 中使用的
项目

you need add proguard rules in proguard-rules.pro file every library(dependencies) like retrofit..etc using in
project

缘字诀 2025-01-22 15:49:40

如果您使用 ProGuard,则需要将规则添加到 proguard-rules.pro 配置中,以涵盖运行时序列化的所有类。

Add dependency on serialization runtime library:

<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-serialization-json</artifactId>
    <version>${serialization.version}</version>
</dependency>

以下配置为收缩后保留的所有可序列化类保留序列化器。取消注释并修改最后一部分,以防您使用命名伴生对象序列化类。

# 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>
lt;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;
#}

如果您想要排除已使用但从未在运行时序列化的可序列化类,则需要使用更窄的类规范编写自定义规则。

自定义规则示例

-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;
}

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>
lt;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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文