前言:
项目中实体类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在页面间传递。