有时会遇到这样的 json 数组:数组中的每个元素是某个基类的子类。这样的数组在 Java 里通常表示为 List<BaseItem>
,使用 Gson
库可以很方便的序列化它,反过来就不容易了。
典型的场景:IM 消息,通常用 List<Msg>
表示,List
中是 Msg
的各种子类,如 TextMsg
, ImageMsg
, EmojiMsg
, VoiceMsg
等。
再比如,模板化的场景,信息流的卡片列表,或者一个采集信息的 App,卡片是待填写的字段,卡片用 List<Card>
表示,List
中是 Card
的各种子类,如 TextInputCard
,TakePicturesCard
,GetLocationCard
等。
+------------------+
| List<Card> |
+------------------+
| TextInputCard |
| GetLocationCard |
| TakePicturesCard |
| TakePicturesCard |
+------------------+
这个库就是要解决像这样的异构 json 列表的反序列化问题。
参考 example
模块,以下是要点总结。
本库已上传到 Maven Central Repository。以 Gradle 为例:
repositories {
// use google maven repo, required if used in non-android project
// to download com.android.support:support-annotations
google()
// if your gradle version is lower than 4.0, use the following syntax
// maven { url "https://maven.google.com" }
jcenter()
}
dependencies {
compile "run.yang.lib:heterogeneous-json-list:1.0.1"
}
- 以
List<Card>
为例,对应的 json 在这里,Card
的子类有TakePicturesCard
,GetLocationCard
,TextInputCard
。 - 每个卡片都有
cardType
字段,表示卡片的类型(类型可以是String
,int
,long
类型), 这是使用本库的关键。对于 IM 消息,可以用msgType
作为这个标识字段。
以上面的 Card
类型为例:
-
实现 CardTypeAdapterFactory , 继承
BaseTypeAdapterFactory
,CardTypeAdapter
继承BaseGenericTypeAdapter
。
- 反序列化回来的
List<Card>
可能出现元素为null
的情况。原因:遇到未知的cardType
, 这种情况不抛出异常是为了在服务端动态下发模板配置的情况下,兼容旧版本的模板。 - 表示类型的字段可以是
String
,int
或long
类型,json 可以自适应
见 这篇文章