gson解析不了RealmList的解决方法

Realm和gson混合使用的时候,包含如下字段的时候要么Realm不行,要么gson解析不了

1
@SerializedName("Files") var files: RealmList<String>? = null

这种情况下Realm无法对String处理,必须对String进行封装处理

1
2
3
4
5
open class RealmString(var value: String? = null) : RealmObject() {
override fun toString(): String {
return value ?: "null"
}
}

修改为:

1
@SerializedName("Files") var files: RealmList<RealmString>? = null

又发现:gson又解析不了,原因是它认为RealmString是一个Object,必须用{}包围起来,也就是说原来是"abc"这样的字符串要变成{value:"abc"}这样子才能正常解析出来

所以,通过自定义序列化/反序列化类来注册到gson中解决这个问题:

1
2
3
4
5
6
7
8
9
10
open class StringRealmListConverter : JsonSerializer<RealmString>, JsonDeserializer<RealmString> {
override fun serialize(src: RealmString, typeOfSrc: Type, context: JsonSerializationContext): JsonElement? {
return context.serialize(src.value)
}

override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): RealmString {
return RealmString(context.deserialize(json, String::class.java))
}

}

在gson解析前:

1
2
3
4
5
6
7
8
9
10
11
12
val gson = GsonBuilder()
.registerTypeAdapter(realmStringType, StringRealmListConverter())
.setExclusionStrategies(object : ExclusionStrategy {
override fun shouldSkipField(f: FieldAttributes?): Boolean {
return f?.declaringClass == RealmObject::class.java
}

override fun shouldSkipClass(clazz: Class<*>?): Boolean {
return false
}
}).create()
return gson.fromJson(str, T::class.java)

这样就OK了。