安卓SharedPreference的详解及总结

        这段时间在做一个新的项目,大家都知道项目中必不可少的是数据的存储,今天想讲解的是轻量级的SharedPreference的存储,之所以想写这篇文章是因为在项目的开发过程中在进入app做的数据存储,退出app存储的数据就没了,我就瞬间懵逼,以为自己写的SharedPreference工具类有问题,就一直在断点,断点发现没问题又去看SharedPreference的源码,到最后还是没找到问题的所在。最后去看退出app的相关操作,才发现另外一个同事在退出的时候把SharedPreference里面的数据全清空了,瞬间内心是崩溃的大哭。。。。。。。不过也好,至少自己更加清楚了SharedPreference。

      首先简单介绍一下SharedPreference:

         它的特点是:1. 只支持java的基本数据类型,不支持自定义数据类型;
                                 2. app内部数据共享,因为文件存储在手机中,所以存储时间久;
                                 3. 使用xml的方式存储,只需要关注key value,使用非常的方便简单 ;


     那么接下来看是怎么用的:

        存储数据:

SharedPreferences sp = getSharedPreferences("SP_TEST", Context.MODE_PRIVATE);
Editor editor = sp.edit();
editor.putString("name", "小明");
editor.putInt("age", 11);
editor.commit();

 

       在这里需要提醒不要写成:

sp.edit().putString("name", "小明");
sp.edit().putInt("age", 11);
sp.edit().commit();

       写成这样的话是无法存储数据的,以为sp.edit()返回的是editor的对象,如果写成这样会导致不是同一个对象在操作,Editor的实现类EditorImpl里面会有一个缓存的Map,最后commit的时候先将缓存里面的Map写入内存中的Map,然后将内存中的Map写进XML文件中。使用上面的方式commit,由于sp.edit()又重新返回了一个新的Editor对象,缓存中的Map是空的,所以导致数据无法被存储,大家只需要稍微注意下就好。 

     获取数据:

SharedPreferences sp = getSharedPreferences("SP_TEST", Context.MODE_PRIVATE);
String name = sp.getString("name", null);
int age = sp.getInt("age", 0);


    如果你没有存储这个值,那么String类型的默认返回null,int类型的默认返回的是o;
   通过以上的讲解相信大家都会用了,但是你如果是as开发的话就会发现官方推荐的是apply()方法而不是commit()方法,这样大家就有疑惑了,两个方法有啥区别呢?那我们先看下官方怎么说:


Commit your preferences changes back from this Editor to the SharedPreferences object it is editing. This atomically performs the requested modifications, 
replacing whatever is currently in the SharedPreferences.

Note that when two editors are modifying preferences at the same time, the last one to call apply wins.

Unlike commit(), which writes its preferences out to persistent storage synchronously, apply() commits its changes to the in-memory SharedPreferences 
immediately but starts an asynchronous commit to disk and you won't be notified of any failures. If another editor on this SharedPreferences does a 
regular commit() while a apply() is still outstanding, the commit() will block until all async commits are completed as well as the commit itself.

As SharedPreferences instances are singletons within a process, it's safe to replace any instance of commit() with apply() if you were already ignoring 
the return value.

You don't need to worry about Android component lifecycles and their interaction with apply() writing to disk. The framework makes sure in-flight disk 
writes from apply() complete before switching states.

The SharedPreferences.Editor interface isn't expected to be implemented directly. However, if you previously did implement it and are now getting errors 
about missing apply(), you can simply call commit() from apply(). 



这段英文的意思很简单,大致总结下来就是:

1、apply没有返回值,commit会返回一个Boolean值,表明是否修改成功。

2、apply方法是将share的修改提交到内存而后异步写入磁盘,但是commit是直接写入磁盘,这就造成两者性能上的差异,犹如apply不直接写入磁盘而share本身是单例创建,apply方法会覆写之前内存中的值,异步写入磁盘的值只是最后的值,而commit每次都要写入磁盘,而磁盘的写入相对来说是很低效的,所以apply方法在频繁调用时要比commit效率高很多。

3、apply方法不会提示任何失败的提示。


由于在一个进程中,sharedPreference是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,建议使用apply,当然需要确保提交成功且有后续操作的话,还是需要commit的。

好了今天的博客就到这,下面把自己写的 sharedPreference的工具类贴出来:

public class SPUtils {

    private SharedPreferences        sp;
    private SharedPreferences.Editor editor;

    /**
     * SPUtils构造函数
     * <p>在Application中初始化</p>
     *
     * @param context 上下文
     * @param spName  spName
     */
    public SPUtils(Context context, String spName) {
        sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        editor = sp.edit();
        editor.apply();
    }

    /**
     *  获取用户信息的SharedPreferences
     * @param context 上下文
     * ConstUtils.SP_NAME  "appInfo"
     * @return
     */
    public static SPUtils getUserSp(Context context){
        SPUtils spUtils = new SPUtils(context, ConstUtils.SP_NAME);
        return  spUtils;
    }
    /**
     * SP中写入String类型value
     *
     * @param key   键
     * @param value 值
     */
    public void putString(String key, String value) {
        editor.putString(key, value).apply();
    }

    /**
     * SP中读取String
     *
     * @param key 键
     * @return 存在返回对应值,不存在返回默认值{@code null}
     */
    public String getString(String key) {
        return getString(key, null);
    }

    /**
     * SP中读取String
     *
     * @param key          键
     * @param defaultValue 默认值
     * @return 存在返回对应值,不存在返回默认值{@code defaultValue}
     */
    public String getString(String key, String defaultValue) {
        return sp.getString(key, defaultValue);
    }

    /**
     * SP中写入int类型value
     *
     * @param key   键
     * @param value 值
     */
    public void putInt(String key, int value) {
        editor.putInt(key, value).apply();
    }

    /**
     * SP中读取int
     *
     * @param key 键
     * @return 存在返回对应值,不存在返回默认值-1
     */
    public int getInt(String key) {
        return getInt(key, -1);
    }

    /**
     * SP中读取int
     *
     * @param key          键
     * @param defaultValue 默认值
     * @return 存在返回对应值,不存在返回默认值{@code defaultValue}
     */
    public int getInt(String key, int defaultValue) {
        return sp.getInt(key, defaultValue);
    }

    /**
     * SP中写入long类型value
     *
     * @param key   键
     * @param value 值
     */
    public void putLong(String key, long value) {
        editor.putLong(key, value).apply();
    }

    /**
     * SP中读取long
     *
     * @param key 键
     * @return 存在返回对应值,不存在返回默认值-1
     */
    public long getLong(String key) {
        return getLong(key, -1L);
    }

    /**
     * SP中读取long
     *
     * @param key          键
     * @param defaultValue 默认值
     * @return 存在返回对应值,不存在返回默认值{@code defaultValue}
     */
    public long getLong(String key, long defaultValue) {
        return sp.getLong(key, defaultValue);
    }

    /**
     * SP中写入float类型value
     *
     * @param key   键
     * @param value 值
     */
    public void putFloat(String key, float value) {
        editor.putFloat(key, value).apply();
    }

    /**
     * SP中读取float
     *
     * @param key 键
     * @return 存在返回对应值,不存在返回默认值-1
     */
    public float getFloat(String key) {
        return getFloat(key, -1f);
    }

    /**
     * SP中读取float
     *
     * @param key          键
     * @param defaultValue 默认值
     * @return 存在返回对应值,不存在返回默认值{@code defaultValue}
     */
    public float getFloat(String key, float defaultValue) {
        return sp.getFloat(key, defaultValue);
    }

    /**
     * SP中写入boolean类型value
     *
     * @param key   键
     * @param value 值
     */
    public void putBoolean(String key, boolean value) {
        editor.putBoolean(key, value).apply();
    }

    /**
     * SP中读取boolean
     *
     * @param key 键
     * @return 存在返回对应值,不存在返回默认值{@code false}
     */
    public boolean getBoolean(String key) {
        return getBoolean(key, false);
    }

    /**
     * SP中读取boolean
     *
     * @param key          键
     * @param defaultValue 默认值
     * @return 存在返回对应值,不存在返回默认值{@code defaultValue}
     */
    public boolean getBoolean(String key, boolean defaultValue) {
        return sp.getBoolean(key, defaultValue);
    }

    /**
     * SP中获取所有键值对
     *
     * @return Map对象
     */
    public Map<String, ?> getAll() {
        return sp.getAll();
    }

    /**
     * SP中移除该key
     *
     * @param key 键
     */
    public void remove(String key) {
        editor.remove(key).apply();
    }

    /**
     * SP中是否存在该key
     *
     * @param key 键
     * @return {@code true}: 存在<br>{@code false}: 不存在
     */
    public boolean contains(String key) {
        return sp.contains(key);
    }

    /**
     * SP中清除所有数据
     */
    public void clear() {
        editor.clear().apply();
    }
}

仅自勉,不喜勿喷。



  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值