Android SharedPreferences singleton pattern (II)

Another project SP tools, and time required before a class of tools to integrate it.

import android.content.Context;
import android.content.SharedPreferences;

import androidx.annotation.NonNull;

import com.google.gson.Gson;
import com.guangsu.messenger.MyApplication;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * SharedPreferences极致封装
 * https://www.jianshu.com/p/895df2258282
 * commit()方法会同步地将偏好值(Preference)直接写入持久化存储设备,
 * 而apply()方法会立即把修改内容提交到SharedPreferences内容缓存中,
 * 然后开始异步的将修改提交到存储设备上,在这个过程中,开发者不会察觉到任何错误问题。
 * <p>
 * 这两个方法的区别在于:
 * 1. apply没有返回值而commit返回boolean表明修改是否提交成功
 * 2. apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘,
 * 而commit是同步的提交到硬件磁盘,
 * 因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。
 * 而apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率。
 * 3. apply方法不会提示任何失败的提示。
 * <p>
 * 由于在一个进程中,sharedPreference是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,建议使用apply,
 * 当然需要确保提交成功且有后续操作的话,还是需要用commit的。
 */
public class SPUtils {
    //保存在手机里面的文件名
    public static final String FILE_NAME = "messenger_cache";
    public static SharedPreferences sp;

    private static SharedPreferences init(Context context) {
        return sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
    }

    /**
     * 存
     *
     * @param key   键
     * @param value 值
     * @param <E>   泛型,自动根据值进行处理
     */
    public static <E> void put(@NonNull String key, @NonNull E value) {
        put(MyApplication.getInstance(), key, value);
    }

    /**
     * 取
     *
     * @param key          键
     * @param defaultValue 默认值
     * @param <E>          泛型,自动根据值进行处理
     * @return
     */
    public static <E> E get(@NonNull String key, @NonNull E defaultValue) {
        return get(MyApplication.getInstance(), key, defaultValue);
    }

    /**
     * 插件间和宿主共用数据 必须 传入context
     *
     * @param context
     * @param key
     * @param value
     * @return
     */
    public static <E> void put(Context context, @NonNull String key, @NonNull E value) {
        SharedPreferences.Editor editor = init(context).edit();
        if (value instanceof String || value instanceof Integer || value instanceof Boolean ||
                value instanceof Float || value instanceof Long || value instanceof Double) {
            editor.putString(key, String.valueOf(value));
        } else {
            editor.putString(key, new Gson().toJson(value));
        }
        SPCompat.apply(editor);
    }


    /**
     * 插件间和宿主共用数据 必须 传入context
     *
     * @param key
     * @param defaultValue
     * @return
     */
    public static <E> E get(Context context, @NonNull String key, @NonNull E defaultValue) {
        String value = init(context).getString(key, String.valueOf(defaultValue));
        if (defaultValue instanceof String) {
            return (E) value;
        }
        if (defaultValue instanceof Integer) {
            return (E) Integer.valueOf(value);
        }
        if (defaultValue instanceof Boolean) {
            return (E) Boolean.valueOf(value);
        }
        if (defaultValue instanceof Float) {
            return (E) Float.valueOf(value);
        }
        if (defaultValue instanceof Long) {
            return (E) Long.valueOf(value);
        }
        if (defaultValue instanceof Double) {
            return (E) Double.valueOf(value);
        }
        //json为null的时候返回对象为null,gson已处理
        return (E) new Gson().fromJson(value, defaultValue.getClass());
    }


    /**
     * 移除某个key值已经对应的值
     *
     * @param context
     * @param key
     */
    public static void remove(Context context, String key) {
        SharedPreferences.Editor editor = init(context).edit();
        editor.remove(key);
        SPCompat.apply(editor);
    }

    /**
     * 清除所有数据
     *
     * @param context
     */
    public static void clear(Context context) {
        SharedPreferences.Editor editor = init(context).edit();
        editor.clear();
        SPCompat.apply(editor);
    }

    /**
     * 查询某个key是否已经存在
     *
     * @param context
     * @param key
     * @return
     */
    public static boolean contains(Context context, String key) {
        return init(context).contains(key);
    }

    public static boolean contains(String key) {
        return contains(MyApplication.getInstance(), key);
    }

    /**
     * 返回所有的键值对
     *
     * @param context
     * @return
     */
    public static Map<String, ?> getAll(Context context) {
        return init(context).getAll();
    }

    /**
     * 保存对象到sp文件中 被保存的对象须要实现 Serializable 接口
     *
     * @param key
     * @param value
     */
    public static void saveObject(String key, Object value) {
        put(key, value);
    }

    /**
     * desc:获取保存的Object对象
     *
     * @param key
     * @return modified:
     */
    public static <T> T readObject(String key, Class<T> clazz) {
        try {
            return get(key, clazz.newInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     *
     * @author
     */
    private static class SPCompat {
        private static final Method S_APPLY_METHOD = findApplyMethod();

        /**
         * 反射查找apply的方法
         *
         * @return
         */
        @SuppressWarnings({"unchecked", "rawtypes"})
        private static Method findApplyMethod() {
            try {
                Class clz = SharedPreferences.Editor.class;
                return clz.getMethod("apply");
            } catch (NoSuchMethodException e) {

            }
            return null;
        }

        /**
         * 如果找到则使用apply执行,否则使用commit
         *
         * @param editor
         */
        public static void apply(SharedPreferences.Editor editor) {
            try {
                if (S_APPLY_METHOD != null) {
                    S_APPLY_METHOD.invoke(editor);
                    return;
                }
            } catch (Exception e) {

            }
            editor.commit();
        }
    }
}

Published 59 original articles · won praise 88 · views 190 000 +

Guess you like

Origin blog.csdn.net/geofferysun/article/details/103449188