android - Moshi 1.9.x 无法序列化 Kotlin 类型

标签 android json robolectric moshi

升级到 Moshi 1.9.1 (从 1.8.0 )后,我遇到以下崩溃和堆栈跟踪:

java.lang.IllegalArgumentException: Cannot serialize Kotlin type com.garpr.android.data.models.RankedPlayer. Reflective serialization of Kotlin classes without using kotlin-reflect has undefined and unexpected behavior. Please use KotlinJsonAdapter from the moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact.
for class com.garpr.android.data.models.RankedPlayer
for class com.garpr.android.data.models.AbsPlayer

    at com.squareup.moshi.Moshi$LookupChain.exceptionWithLookupStack(Moshi.java:349)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:150)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:98)
    at com.squareup.moshi.AdapterMethodsFactory$AdapterMethod.bind(AdapterMethodsFactory.java:313)
    at com.squareup.moshi.AdapterMethodsFactory.create(AdapterMethodsFactory.java:62)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:138)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:98)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:72)
    at com.garpr.android.data.converters.AbsPlayerConverterTest.setUp(AbsPlayerConverterTest.kt:76)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:546)
    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:252)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Cannot serialize Kotlin type com.garpr.android.data.models.RankedPlayer. Reflective serialization of Kotlin classes without using kotlin-reflect has undefined and unexpected behavior. Please use KotlinJsonAdapter from the moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact.
    at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:83)
    at com.squareup.moshi.Moshi.nextAdapter(Moshi.java:169)
    at com.squareup.moshi.AdapterMethodsFactory$AdapterMethod.bind(AdapterMethodsFactory.java:312)
    at com.squareup.moshi.AdapterMethodsFactory.create(AdapterMethodsFactory.java:62)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:138)
    ... 23 more

我看到了 this other Stack Overflow answer ,但它不适用于我,因为我已经将相关的 @JsonClass(generateAdapter = X) 行添加到我的类中。

我为 AbsPlayerConverter class 类使用自定义 AbsPlayer,这样我就可以确定要解析到哪个子类。然后,如果它解析为 RankedPlayer ,我将使用另一个自定义转换器 ( RankedPlayerConverter )。

这是my Moshi-builder code:

Moshi.Builder()
        .add(AbsPlayerConverter)
        .add(AbsRegionConverter)
        .add(AbsTournamentConverter)
        .add(MatchConverter)
        .add(RankedPlayerConverter)
        .add(SimpleDateConverter)
        .build()

这是 my gradle file 中的 Moshi:

implementation "com.squareup.moshi:moshi:1.9.1"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.9.1"

最后,在了解了所有这些文字和信息之后,我不知道如何会遇到这次崩溃。我清楚地定义了如何序列化/反序列化我的 RankedPlayer 类。如果我降级到 Moshi 1.8.0,并完全按原样保留我的代码库,则此崩溃就会消失,一切都会完美运行。

大家有什么想法吗?

谢谢!!

最佳答案

错误消息特别指出请使用 moshi-kotlin Artifact 中的 KotlinJsonAdapter 或使用 moshi-kotlin-codegen Artifact 中的代码生成

根据 Kotlin part of the readme ,如果您不使用 Moshi 的 codegen,则必须添加 KotlinJsonAdapterFactory。这是 Moshi 1.9 中的特定行为更改,如 the blog post about Moshi 1.9 所示。 .

Moshi.Builder()
    .add(AbsPlayerConverter)
    .add(AbsRegionConverter)
    .add(AbsTournamentConverter)
    .add(MatchConverter)
    .add(RankedPlayerConverter)
    .add(SimpleDateConverter)
    .add(KotlinJsonAdapterFactory())
    .build()

并确保您使用implementation("com.squareup.moshi:moshi-kotlin:1.9.1")

关于android - Moshi 1.9.x 无法序列化 Kotlin 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58677339/

相关文章:

android - ADB - Android - 获取当前 Activity 的名称

android - 如何在 list 中将平板电脑的方向设置为手机的横向和纵向?

javascript - JSPlumb 图到 JSON

json - Bing 搜索 API 的基本身份验证

mocking - robolectric 3.0 Mockito -- 如何在事件中模拟类

android - kotlin 和 ArgumentCaptor - IllegalStateException

android - 用 robolectric 测试 toast

android - 如何让用户使用我的应用程序播放视频?

android - BackStack Fragments 旋转时空白

json - 如何使用 Handlebars.js、JSON 和多页面 jQuery Mobile 获取动态页面?