问题
I have the following dependencies:
moshi-codegen: 1.10.0
kotlin: 1.4.10
Android Gradle Plugin: 4.0.1
R8 is enabled in the build.
At runtime, i got the following stacktrace when Moshi tries to parse enums
java.lang.AssertionError: Missing field in e.f.a.k.c.b.a
at com.squareup.moshi.StandardJsonAdapters$EnumJsonAdapter.<init>(SourceFile:246)
at com.squareup.moshi.StandardJsonAdapters$1.create(SourceFile:67)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.tsystems.tpay.data.client.models.ContactApiModelJsonAdapter.<init>(SourceFile:30)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at com.squareup.moshi.internal.Util.generatedAdapter(SourceFile:553)
at com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory.create(SourceFile:193)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.squareup.moshi.Moshi.adapter(SourceFile:101)
at com.squareup.moshi.Moshi.adapter(SourceFile:71)
at com.squareup.moshi.CollectionJsonAdapter.newArrayListAdapter(SourceFile:52)
at com.squareup.moshi.CollectionJsonAdapter$1.create(SourceFile:36)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.squareup.moshi.Moshi.adapter(SourceFile:101)
at p.z.a.a.a(SourceFile:91)
at p.u.a(SourceFile:352)
at p.u.b(SourceFile:335)
at p.k.a(SourceFile:113)
at p.k.a(SourceFile:82)
at p.v.a(SourceFile:37)
at p.u.a(SourceFile:192)
at p.u$a.invoke(SourceFile:149)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy14.c(Unknown Source)
at e.f.a.k.b.f$g.a(SourceFile:87)
at i.b0.j.a.a.b(SourceFile:33)
at j.a.v0.run(SourceFile:241)
at j.a.g3.a.a(SourceFile:594)
at j.a.g3.a.a(SourceFile:60)
at j.a.g3.a$b.run(SourceFile:740)
Caused by: java.lang.NoSuchFieldException: PERSONAL
at java.lang.Class.getField(Class.java:1604)
at com.squareup.moshi.StandardJsonAdapters$EnumJsonAdapter.<init>(SourceFile:240)
According to the README, i do not have to add R8 rules manually, but maybe enums are exceptions?
回答1:
Yes enum should be treated a bit differently and there is currently a pending PR to update the README file (as of the time of writing) https://github.com/square/moshi/pull/1216.
You have 2 options:
- Add
@JsonAdapter(generateAdapter = false)
on top of your enum definition. - Add a proguard rule to keep your enum's fields e.g.,
-keepclassmembers enum your.model.package.YourEnum {
<fields>;
**[] values();
}
Reason:
According to the code here https://github.com/square/moshi/blob/0c85eae34af00ecbee46beaa5b25fb4af00fb9f2/moshi/src/main/resources/META-INF/proguard/moshi.pro#L10, Enum field names are used by the integrated EnumJsonAdapter
. Also values()
is synthesized by the Kotlin compiler and is used by EnumJsonAdapter
indirectly.
Also note on the same file that Moshi has generated a pre-made proguard rule which is inherited by your app:
-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
<fields>;
**[] values();
}
This rule is basically applied to all classes annotated by the @JsonClass
annotation, so if you add the annotation (Option#1), your class would be covered by this rule.
Alternatively if you don't want adding the annotation, you can add the rule specifically for your class aka Option#2.
来源:https://stackoverflow.com/questions/64068151/enum-parsing-fails-with-moshi-and-r8