我正在编写一个android应用程序,我想在其中序列化这个Anime.java
类的示例。它的超类AnimeBase.java
有一个名为aired
的字段,它的类型是DateRange
。这个DateRange
包含两个字段:
public LocalDate from;
public LocalDate to;
序列化非常简单(使用gson),如下所示:
final Gson gson = new Gson();
String data = gson.toJson(obj);
但是,在我的结果中,from
和to
字段总是空的,如下所示:
// ...
"trailer_url": "https://www.youtube.com/embed/SlNpRThS9t8?enablejsapi\u003d1\u0026wmode\u003dopaque\u0026autoplay\u003d1",
"aired": {
"from": {}
},
"episodes": 16,
// ...
在这里,to
为空,因此它是缺失的(这没关系)。
为什么gson没有序列化这两个LocalDate
?它是否与DateRange
的setter和getter有关(这有点不寻常,使用OffsetDateTime
而不是LocalDate
)?
由于这些类来自第三方库,有没有一种好的方法来处理这个问题,而不用复制我自己的应用程序中的所有模型类来序列化/反序列化它们?
2条答案
按热度按时间ugmeyewa1#
看一下https://github.com/gkopff/gson-javatime-serialisers有LocalDate对象的序列化程序。
如果您选择建立自己的序列化程式:
s4chpxco2#
我现在可以找到这个问题的根源了。
从Android 9开始,Google添加了一个名为“Restrictions on non-SDK interfaces“的东西,他们在Android dalvik运行时中限制对未公开记录的SDK接口的访问。
由于Gson默认使用
ReflectiveTypeAdapterFactory
,而ReflectiveTypeAdapterFactory
本身在要序列化的对象中查找可序列化字段,因此它严重依赖于反射。Google已经记录了这种行为,即
ReflectiveTypeAdapterFactory
使用的函数Class.getDeclaredFields()
只返回公共可访问字段,或者更具体地说,只返回Google列入白名单的字段。https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces#results-of-keeping-non-sdk在参考文档中,Google明确地将java.time.LocalDate字段声明为灰名单:
我不知道为什么这个访问仍然在发布模式下工作,只有当构建版本是
debuggable
时才会出现这种行为,但我想这也是未来Android版本中将删除的东西。因此,我们添加了自己的向后兼容串行化器(类似于@k1r0的串行化器,但仍然可以处理以前的串行化值):