【问题标题】:Moshi with Proguard Didn't find class JsonAdapter带有 Proguard 的 Moshi 没有找到 JsonAdapter 类
【发布时间】:2022-01-26 05:55:00
【问题描述】:

我似乎无法弄清楚这个问题......

我尝试了各种方法来保留所需的类并搜索了很长时间以找到解决方案....

当我应用 pro Guard 时,应用程序因此错误而崩溃。

我将改造 2.9.0 和 moshi 1.13.0 与 moshi-kotlin 1.13.0 一起使用

原因:java.lang.ClassNotFoundException:找不到类 ApiResponseJsonAdapter

ApiResponse 是具有通用类型的模型

@Keep
@JsonClass(generateAdapter = true)
data class ApiResponse<T>(
    @Json(name = "detail")
    val message: String,
    @Json(name = "result")
    val result: T
)

我需要帮助。 提前致谢。

更新 这是我的职业后卫

-keepattributes SourceFile,LineNumberTable

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

-keep class com.example.base.ApiResponse { *; }
-keepclassmembers class com.example.base.ApiResponse.** {
  <init>(...);
  <fields>;
}
-keep class com.example.data.entity.server.** { *; }
-keepclassmembers class com.example.data.entity.server.** {
  <init>(...);
  <fields>;
}

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

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

-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
    <fields>;
}

-keepnames @com.squareup.moshi.JsonClass class *

-keepclasseswithmembers class **.*JsonAdapter extends com.squareup.moshi.JsonAdapter {
    <init>(...);
    <fields>;
}

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

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

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

# Understand the @Keep support annotation.
-keep class androidx.annotation.Keep

-keep @androidx.annotation.Keep class * {*;}

-keepclasseswithmembers class * {
    @androidx.annotation.Keep <methods>;
}

-keepclasseswithmembers class * {
    @androidx.annotation.Keep <fields>;
}

-keepclasseswithmembers class * {
    @androidx.annotation.Keep <init>(...);
}

-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*


-allowaccessmodification
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''

-keep public class * extends androidx.appcompat.app.AppCompatActivity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference

# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}


# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
    native <methods>;
}


-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}


-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}


# Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
  public static <fields>;
}


# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

#-keep public class * {
#    public protected *;
#}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keepattributes Signature

-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}

-keepattributes *Annotation*

-dontwarn com.airbnb.lottie.**
-keep class com.airbnb.lottie.** {*;}

# 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

# 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

-dontwarn com.google.auto.service.AutoService
-dontwarn javax.lang.model.SourceVersion
-dontwarn javax.lang.model.element.AnnotationMirror
-dontwarn javax.lang.model.element.Element
-dontwarn javax.lang.model.element.ElementKind
-dontwarn javax.lang.model.element.ElementVisitor
-dontwarn javax.lang.model.element.ExecutableElement
-dontwarn javax.lang.model.element.Modifier
-dontwarn javax.lang.model.element.Name
-dontwarn javax.lang.model.element.TypeElement
-dontwarn javax.lang.model.element.TypeParameterElement
-dontwarn javax.lang.model.element.VariableElement
-dontwarn javax.lang.model.type.ArrayType
-dontwarn javax.lang.model.type.DeclaredType
-dontwarn javax.lang.model.type.ExecutableType
-dontwarn javax.lang.model.type.TypeKind
-dontwarn javax.lang.model.type.TypeMirror
-dontwarn javax.lang.model.type.TypeVariable
-dontwarn javax.lang.model.type.TypeVisitor
-dontwarn javax.lang.model.util.AbstractTypeVisitor8
-dontwarn javax.lang.model.util.ElementFilter
-dontwarn javax.lang.model.util.Elements
-dontwarn javax.lang.model.util.SimpleElementVisitor8
-dontwarn javax.lang.model.util.SimpleTypeVisitor8
-dontwarn javax.lang.model.util.Types
-dontwarn org.bouncycastle.jsse.BCSSLParameters
-dontwarn org.bouncycastle.jsse.BCSSLSocket
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
-dontwarn org.conscrypt.Conscrypt$Version
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.ConscryptHostnameVerifier
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
-dontwarn java.util.concurrent.Flow*

错误堆栈跟踪

java.lang.IllegalArgumentException: Unable to create converter for com.example.base.ApiResponse<com.example.data.entity.server.Info>
    for method a5.b
    at an2.n(SourceFile:54)
    at ii0.e(SourceFile:126)
    at ii0.f(SourceFile:85)
    at cz1.b(SourceFile:39)
    at tt1.c(SourceFile:202)
    at tt1$a.invoke(SourceFile:160)
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
    at $Proxy3.b(Unknown Source)
    at k4.b(SourceFile:46)
    at z4.b(SourceFile:72)
    at jf0.a(SourceFile:6)
    at com.example.presentation.ViewModel.m(SourceFile:27)
    at p4.C1(SourceFile:70)
    at td.G0(SourceFile:33)
    at androidx.fragment.app.Fragment.f1(SourceFile:3019)
    at androidx.fragment.app.h.f(SourceFile:551)
    at androidx.fragment.app.h.m(SourceFile:261)
    at androidx.fragment.app.FragmentManager.Z(SourceFile:1840)
    at androidx.fragment.app.FragmentManager.X0(SourceFile:1758)
    at androidx.fragment.app.FragmentManager.W(SourceFile:1701)
    at androidx.fragment.app.FragmentManager$d.run(SourceFile:488)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7664)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
 Caused by: java.lang.RuntimeException: Failed to find the generated JsonAdapter class for com.example.base.ApiResponse<com.example.data.entity.server.Info>
    at com.squareup.moshi.internal.a.d(SourceFile:590)
    at com.squareup.moshi.StandardJsonAdapters$b.create(SourceFile:61)
    at com.squareup.moshi.g.f(SourceFile:146)
    at com.squareup.moshi.g.e(SourceFile:106)
    at a81.d(SourceFile:89)
    at tt1.f(SourceFile:362)
    at tt1.h(SourceFile:345)
    at ii0.e(SourceFile:124)
    at ii0.f(SourceFile:85) 
    at cz1.b(SourceFile:39) 
    at tt1.c(SourceFile:202) 
    at tt1$a.invoke(SourceFile:160) 
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006) 
    at $Proxy3.b(Unknown Source) 
    at k4.b(SourceFile:46) 
    at z4.b(SourceFile:72) 
    at jf0.a(SourceFile:6) 
    at com.example.presentation.ViewModel.m(SourceFile:27) 
    at p4.C1(SourceFile:70) 
    at td.G0(SourceFile:33) 
    at androidx.fragment.app.Fragment.f1(SourceFile:3019) 
    at androidx.fragment.app.h.f(SourceFile:551) 
    at androidx.fragment.app.h.m(SourceFile:261) 
    at androidx.fragment.app.FragmentManager.Z(SourceFile:1840) 
    at androidx.fragment.app.FragmentManager.X0(SourceFile:1758) 
    at androidx.fragment.app.FragmentManager.W(SourceFile:1701) 
    at androidx.fragment.app.FragmentManager$d.run(SourceFile:488) 
    at android.os.Handler.handleCallback(Handler.java:938) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:223) 
    at android.app.ActivityThread.main(ActivityThread.java:7664) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
 Caused by: java.lang.ClassNotFoundException: com.example.base.ApiResponseJsonAdapter
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:454)
    at com.squareup.moshi.internal.a.d(SourceFile:564)
    at com.squareup.moshi.StandardJsonAdapters$b.create(SourceFile:61) 
    at com.squareup.moshi.g.f(SourceFile:146) 
    at com.squareup.moshi.g.e(SourceFile:106) 
    at a81.d(SourceFile:89) 
    at tt1.f(SourceFile:362) 
    at tt1.h(SourceFile:345) 
    at ii0.e(SourceFile:124) 
    at ii0.f(SourceFile:85) 
    at cz1.b(SourceFile:39) 
    at tt1.c(SourceFile:202) 
    at tt1$a.invoke(SourceFile:160) 
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006) 
    at $Proxy3.b(Unknown Source) 
    at k4.b(SourceFile:46) 
    at z4.b(SourceFile:72) 
    at jf0.a(SourceFile:6) 
    at com.example.presentation.ViewModel.m(SourceFile:27) 
    at p4.C1(SourceFile:70) 
    at td.G0(SourceFile:33) 
    at androidx.fragment.app.Fragment.f1(SourceFile:3019) 
    at androidx.fragment.app.h.f(SourceFile:551) 
    at androidx.fragment.app.h.m(SourceFile:261) 
    at androidx.fragment.app.FragmentManager.Z(SourceFile:1840) 
    at androidx.fragment.app.FragmentManager.X0(SourceFile:1758) 
    at androidx.fragment.app.FragmentManager.W(SourceFile:1701) 
    at androidx.fragment.app.FragmentManager$d.run(SourceFile:488) 
    at android.os.Handler.handleCallback(Handler.java:938) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:223) 
    at android.app.ActivityThread.main(ActivityThread.java:7664) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
 Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.base.ApiResponseJsonAdapter" on path:

【问题讨论】:

  • 请出示您的 -keep 尝试,以便我们了解那里出了什么问题。
  • Moshi 是用来序列化和打包数据的吧?
  • @SagarBalyan 是的,就像 Gson 一样
  • @Miha_x64 我已经用 Proguard 信息更新了问题
  • @Jae 你为什么不使用 Gson?我认为它更好。

标签: android moshi


【解决方案1】:

我已经解决了这些问题。 我意识到来自 Moshi 的 Kotlin-codegen 工件没有生成,所以我从终端运行 gradle build 并发现对于 Moshi 需要使用 Java 16,但我使用的是默认的 Android Java。 切换后一切都像魅力一样进行了各种修复,例如

包括以下对属性进行分级的语句。

android.jetifier.ignorelist=moshi-1.13.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2021-09-30
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    相关资源
    最近更新 更多