Android数据存储之SharedPreferences

/ 0评 / 1

什么是SharedPreferences

SharedPreferences是Android中一种轻型数据存储方式,本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息,SharedPreferences对象本身只能获取数据而不支持存储和修改,存储和修改是通过Editor对象实现的,保存位置为/data/data/[package_name]/shared_prefs/下。

实现SharedPreferences存储的步骤

SharedPreferences是一个接口,不能直接实例化,只能使用Context对象提供的方法获取,在Activity中直接使用是因为Activity继承自Context

//获取默认的SharedPreferences
//默认文件名为[package_name]_preferences.xml
SharedPreferences pref=PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
//指定SharedPreferences 存储的xml文件名,权限为私有
SharedPreferences pref=getSharedPreferences("myPref",Context.Mode_PRIVATE);

SharedPreferences.Editor editor = pref.edit();

通过Editor接口的putXxx保存key-value对 Xxx为不同数据类型

editor.putString("name","this is a name");

//类似于数据库,必须提交存储操作才会生效

editor.commit();

//也可以使用如下方法

editor.apply();

关于SharedPreference.Editor的apply()和commit()方法异同

apply方法是将share的修改提交到内存而后异步写入磁盘,commit是直接写入磁盘,这就造成两者性能上的差异,apply方法会覆写之前内存中的值,异步写入磁盘的值只是最后的值,而commit每次都要写入磁盘,而磁盘的写入相对来说是很低效的,所以apply方法在频繁调用时要比commit效率高很多。apply虽然高效但是commit也有着自己的优势那就是它可以返回每次操作的成功与否的返回值。

通过SharedPreferences接口的geXxx获取key-value对 Xxx为不同数据类型

//第一个参数为key,第二个参数为默认值

String str = pref.getString("name","");

通过这种方式存储xml文件的位置在data/data/包名/shared_prefs文件夹下

有时候我们想当SharedPreferences中存储的数据发生变化的时候马上进行处理,这时我们可以使用SharedPreferences的registerOnSharedPreferenceChangeListener方法为其注册一个监听,当不需要继续使用的时候,需要使用SharedPreferences的unregisterOnSharedPreferenceChangeListener方法解除注册。如下

SharedPreferences sharedPre = PreferenceManager.getDefaultSharedPreferences(this);
sharedPre.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener() {

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        sharedPre.unregisterOnSharedPreferenceChangeListener(this);
    }
});

 

有关SharedPreferences的工具类

/**
 * SharedPreferences 工具类
 */
public class SharedPreferencesUtil
{
    /**
     * 保存在手机里面的文件名
     */
    public static final String FILE_NAME = "share_data";

    /**
     * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
     * 
     * @param context
     * @param key
     * @param object
     */
    public static void put(Context context, String key, Object object)
    {

        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();

        if (object instanceof String)
        {
            editor.putString(key, (String) object);
        } else if (object instanceof Integer)
        {
            editor.putInt(key, (Integer) object);
        } else if (object instanceof Boolean)
        {
            editor.putBoolean(key, (Boolean) object);
        } else if (object instanceof Float)
        {
            editor.putFloat(key, (Float) object);
        } else if (object instanceof Long)
        {
            editor.putLong(key, (Long) object);
        } else
        {
            editor.putString(key, object.toString());
        }

        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
     * 
     * @param context
     * @param key
     * @param defaultObject
     * @return
     */
    public static Object get(Context context, String key, Object defaultObject)
    {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);

        if (defaultObject instanceof String)
        {
            return sp.getString(key, (String) defaultObject);
        } else if (defaultObject instanceof Integer)
        {
            return sp.getInt(key, (Integer) defaultObject);
        } else if (defaultObject instanceof Boolean)
        {
            return sp.getBoolean(key, (Boolean) defaultObject);
        } else if (defaultObject instanceof Float)
        {
            return sp.getFloat(key, (Float) defaultObject);
        } else if (defaultObject instanceof Long)
        {
            return sp.getLong(key, (Long) defaultObject);
        }

        return null;
    }

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

    /**
     * 清除所有数据
     * 
     * @param context
     */
    public static void clear(Context context)
    {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        SharedPreferencesCompat.apply(editor);
    }

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

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

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     */
    private static class SharedPreferencesCompat
    {
        private static final Method sApplyMethod = 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 (sApplyMethod != null)
                {
                    sApplyMethod.invoke(editor);
                    return;
                }
            } catch (IllegalArgumentException e)
            {
            } catch (IllegalAccessException e)
            {
            } catch (InvocationTargetException e)
            {
            }
            editor.commit();
        }
    }
}

发表评论

您的电子邮箱地址不会被公开。