前言:
项目中实体类RoutePoint中有一个拓展属性tag:Map<String,Object>如下,给实现Parcelable序列化带来一些困扰。因为Object没有继承Parcelable。
public class MCRoutePoint implements Parcelable {
private Map<String,Object> tag;
}
换一种思路Map<String,Object>序列化
1,针对可以实现Parcelable的Value保持不变:例如基础数据类型、String、Parcelable的子类
2,对于无法现实序列化的Value在write时提前转换成Json类型的String字符串。
3,添加拓展方法getExpand(@NotNull String key, Class<?> clazz)自动解析。
实现结果如下所示:
public class MCRoutePoint implements Parcelable {
/**
* 名称
*/
private String name = null;
/**
* 地址
*/
private String address = null;
/**
* poi的唯一标识,可能为空
*/
private String poiId = null;
private Map<String,Object> tag;
public MCRoutePoint() {
}
protected MCRoutePoint(Parcel in) {
name = in.readString();
address = in.readString();
poiId = in.readString();
this.tag = new HashMap<>();
in.readMap(this.tag, this.getClass().getClassLoader());
}
public static final Creator<MCRoutePoint> CREATOR = new Creator<MCRoutePoint>() {
@Override
public MCRoutePoint createFromParcel(Parcel in) {
return new MCRoutePoint(in);
}
@Override
public MCRoutePoint[] newArray(int size) {
return new MCRoutePoint[size];
}
};
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(address);
dest.writeString(poiId);
if (tag != null) {
for (String key : tag.keySet()) {
Object value = tag.get(key);
if (!isWrapper(value)) {
if (value != null) {
tag.put(key, GsonSingleton.instance().gson().toJson(value));
}
}
}
}
dest.writeMap(tag);
}
public void setExpand(@NotNull String key, Object value){
if (tag == null) {
tag = new HashMap<>();
}
tag.put(key, value);
}
public Object getExpand(@NotNull String key, Class<?> clazz) {
if (tag == null || !tag.containsKey(key)) {
return null;
}
Object value = tag.get(key);
if (clazz != null && !clazz.isInstance(value) && value instanceof String){
return GsonSingleton.instance().gson().fromJson((String) value, clazz);
}
return value;
}
private static Class<?>[] primitiveWrappers = {Integer.class, Float.class, Double.class, Boolean.class, Byte.class, Short.class, Long.class, Character.class, String.class, Parcelable.class};
private boolean isWrapper(Object obj){
if(obj != null){
for (Class<?> wrapper : primitiveWrappers) {
if (wrapper.isInstance(obj)) {
return true; // 是基本数据类型的包装类对象
}
}
}
return false;
}
}
总结:
如此实现后RoutePoint中的tag拓展属性就能存入Bundle在页面间传递。