切換語言為:簡體

Android中Map<String,Object> 實現Parcelable序列化

  • 爱糖宝
  • 2024-10-16
  • 2037
  • 0
  • 0

前言:

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

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.