在反序列化时使用 gson 定义嵌套列表类型

Define nested list type using gson while deserializing

提问人:HiddenCoder7 提问时间:4/30/2023 最后编辑:HiddenCoder7 更新时间:5/6/2023 访问量:276

问:

通过使用新的 AGP v8.0 和启用的完整 R8,当我尝试从 JSON 字符串反序列化嵌套对象时,嵌套对象的类型被 gson 错误地标识为 LinkedTreeMap。

actions_list.json:

    [
    {
    "name": "actionList1",
    "listA": [
      {
        "name": "action1"
      },
      {
        "name": "action2"
      }
    ] // end of listA
    }, // end of actionList1
    ... // actionList1 to actionListN
    ]

操作类:

    data class Action(
    @SerializedName("name") @Expose val name: String,
    val actions: List<MyAction>,
    var a: Int,
    ...
    var n: Boolean,
    )

MyActions.kt:

    data class MyActions(
    @SerializedName("name")
    val name: String,
    var state: MyActionState?
    )

MyActionState.kt:

    enum class MyActionState{
    Nothing, Running, Done, Failed, Deactivate
    }

proguard-rules.pro:

    -keepattributes Signature, InnerClasses, EnclosingMethod
    -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
    -dontwarn javax.annotation.**
    -dontwarn kotlin.Unit
    -dontwarn retrofit2.KotlinExtensions
    -dontwarn retrofit2.KotlinExtensions$*
    -dontwarn okhttp3.**
    -keep class okhttp3.** { *;}
    -dontwarn okio.**
    -keepattributes SourceFile,LineNumberTable
    -keep class com.google.gson.*
    -keep interface com.google.gson.*
    -keep class * extends com.google.gson.reflect.TypeToken
    -keep public class * implements java.lang.reflect.Type
    -keep class path.to.all.app.class
    -keep interface path.to.all.app.class
    -keep enum path.to.all.app.class
    -keepattributes *Annotation*
    -keepattributes AnnotationDefault
    -keepattributes Signature

这就是我如何将json数组转换为List:

    val jsonString: String = this.assets.open("actions/actions_list.json")
    .bufferedReader()
    .use { it.readText() }
    
    val type = TypeToken.getParameterized(List::class.java,Action::class.java).type
    
    return Gson().fromJson(jsonString, type )

当 app build.gradle 中的 minifyEnabled 为 true 时,List 将转换为 LinkedTreeMap。我有太多嵌套对象,有什么方法可以在没有自定义除线器类、TypeConverters、禁用完整 r8 模式和降级 gradle 版本的情况下解决这个问题?

序列化 android-gradle-plugin gson proguard android-r8

评论

1赞 Marcono1234 5/1/2023
你似乎不见了(参见 R8 常见问题解答),你只有 .此外,也许 of 限制性太强,因为 Gson 具有内部非实现,例如 ParameterizedTypeImpl-keep class com.google.gson.reflect.TypeToken { *; }extends ...TypeTokenpublicpublic class * implements java.lang.reflect.Typepublic
0赞 Marcono1234 5/5/2023
上面的评论解决了你的问题吗?(如果是这样,我也可以将其添加为正确的答案)
0赞 HiddenCoder7 5/6/2023
谢谢,但我没有尝试过这个。通过为我的数据添加和路径解决了我的问题。@Marcono1234-keepclassmembernames
0赞 P1NG2WIN 10/10/2023
@Marcono1234无济于事。我用于 gson 反射的 proguard-rules 部分(不是完整的文件代码): 现在我将尝试添加显式嵌套类-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken -keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken -keep class com.google.gson.reflect.TypeToken { *; }

答:

0赞 HiddenCoder7 5/6/2023 #1

将这些行添加到 proguard-rules.pro 解决了该问题:

-keepclassmembernames class path.to.MyActions {<fields>;}
-keepclassmembernames class path.to.Action{<fields>;}