ProGuard:带有 Moshi+Retrofit 的 ClassCastException

问题描述 投票:0回答:2

在调试模式和发布模式下 ProGuard 关闭时工作正常,但在 ProGuard 打开时不能正常工作,即使是空的。

这里是堆栈跟踪:

2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at h9.d0.f(Unknown Source:46)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at h9.y1.b(Unknown Source:39)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at h9.x1.c(Unknown Source:202)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at h9.v1.invoke(Unknown Source:160)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at $Proxy1.signUp(Unknown Source)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at k4.d.l(Unknown Source:35)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at k4.d.p(Unknown Source:8)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at k4.d.s(Unknown Source:4)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at j8.k1.f(Unknown Source:61)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at j8.b.e(Unknown Source:212)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at r4.u1.l(Unknown Source:311)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at o7.a.n(Unknown Source:33)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at g8.a1.run(Unknown Source:106)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at g8.h1.d0(Unknown Source:69)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at g8.b1.e(Unknown Source:244)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at g8.b1.a(Unknown Source:161)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at g8.n.s(Unknown Source:397)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at g8.n.p(Unknown Source:513)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at i8.r0.M(Unknown Source:1079)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at i8.k.V(Unknown Source:546)
2021-09-07 23:42:19.556 32130-32130/com.myapp.packagename W/System.err:     at i8.k.l(Unknown Source:630)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at j8.p.c(Unknown Source:51)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at j8.p.a(Unknown Source:1)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at j8.o.l(Unknown Source:11)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at o7.a.n(Unknown Source:33)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at g8.a1.run(Unknown Source:106)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at androidx.compose.ui.platform.q1.f0(Unknown Source:81)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at androidx.compose.ui.platform.q1.Z(Unknown Source:41)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at androidx.compose.ui.platform.p1.run(Unknown Source:57)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at android.os.Handler.handleCallback(Handler.java:900)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:103)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at android.os.Looper.loop(Looper.java:219)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:8668)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
2021-09-07 23:42:19.557 32130-32130/com.myapp.packagename W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)

我已经尝试过这些 ProGuard 配置,但它们都不起作用。
这里
这里

android proguard classcastexception moshi
2个回答
7
投票

不知何故这

proguard-rules.pro
有效。

# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

-dontwarn kotlin.reflect.jvm.internal.**

-keep class kotlin.reflect.jvm.internal.** { *; }

-keep interface javax.annotation.Nullable

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

# Glide
#-keep public class * implements com.bumptech.glide.module.GlideModule
#-keep public class * extends com.bumptech.glide.module.AppGlideModule

-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault

-keep class com.google.android.gms.** { *; }
-dontwarn com.google.android.gms.*
-keep class com.google.api.client.** {*;}

# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**

#### OkHttp, Retrofit and Moshi
-dontwarn okhttp3.**
-dontwarn retrofit2.Platform.Java8
-dontwarn okio.**
-dontwarn javax.annotation.**
-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}

-keepclasseswithmembers class * {
    @com.squareup.moshi.* <methods>;
}

-keep @com.squareup.moshi.JsonQualifier interface *

# Enum field names are used by the integrated EnumJsonAdapter.
# values() is synthesized by the Kotlin compiler and is used by EnumJsonAdapter indirectly
# Annotate enums with @JsonClass(generateAdapter = false) to use them with Moshi.
-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
    <fields>;
    **[] values();
}

# Keep helper method to avoid R8 optimisation that would keep all Kotlin Metadata when unwanted
-keepclassmembers class com.squareup.moshi.internal.Util {
    private static java.lang.String getKotlinMetadataClassName();
}

-keep class kotlin.Metadata { *; }
-keepclassmembers class kotlin.Metadata {
    public <methods>;
}

-keepclassmembers class * {
    @com.squareup.moshi.FromJson <methods>;
    @com.squareup.moshi.ToJson <methods>;
}

-keepnames @kotlin.Metadata class com.yourpackage.model.**
-keep class com.yourpackage.model.** { *; }
-keepclassmembers class com.yourpackage.model.** { *; }

# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod

# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations

# Keep annotation default values (e.g., retrofit2.http.Field.encoded).
-keepattributes AnnotationDefault

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions.*

# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>

# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response

# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

导致

ClassCastException
的原因,根据我的推论,是缺乏
Moshi
对泛型的支持。这是我高度暂停的数据类是原因:

@JsonClass(generateAdapter = true)
data class ResponseHttp<T>(
    @field:Json(name = "statusCode") val statusCode: String,
    // this generic type is where went wrong
    @field:Json(name = "data") val data: T?,
)

0
投票

对我来说,我只有 Retrofit,它通过将这些行添加到

proguard-rules.pro

中解决了我的问题
#ParametrizedType ClassCastException error fix
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.** { *; }

在我的例子中,我包括了每个 kotlin.coroutines 类,因为我也在这个包中使用了超时作业。 Continuation 也在这个内部,它是进行转换的那个,所以,为了以防万一,我把它全部添加了

© www.soinside.com 2019 - 2024. All rights reserved.