切换语言为:繁体

Android中Map<String,Object> 实现Parcelable序列化

  • 爱糖宝
  • 2024-10-16
  • 2049
  • 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.