前言:
專案中實體類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在頁面間傳遞。