安卓SharedPreference的详解及总结

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

        这段时间在做一个新的项目,大家都知道项目中必不可少的是数据的存储,今天想讲解的是轻量级的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();
    }
}

仅自勉,不喜勿喷。



Android SharedPreference使用及原理分析 ** 一、SharedPreference简单使用 ** 问题: 1.如果两个activity都使用同一个sharedpreference,但是第一个activity没有提交,第二个activity提交了,那么会出现什么结果。 2.不同的进程是否可以共享同一个sharedpreference mode: Context.MODE_PRIVATE:只被本地程序读写 ... 阅读详情

相关推荐

【5年Android从零复盘系列之二十六】Android存储(1):Sharedpreference详解

【5年Android从零复盘系列之二十六】Android存储(1):Sharedpreference 1.概述(注意要点) SharedPreferences是一个轻量级的存储工具类,实际开发中主要用于保存APP基础设置值。 SharedPreference是以键值对key-value形式存储数据 支持直接存储的基础类型有:String 、boolean 、int 、long、float 保存位置:/data/data/app_package_name/shared_prefs/your_sp_name

Cupster 7086

AndroidSharedPreferences详解

一、SharedPreferences 首选项 介绍 存储软件的配置信息 存储的信息:很小,简单的数据;比如:自动登录,记住密码,小说app(返回后再次进入还是 原来看的页数),按钮的状态。 特点:当程序运行首选项里面的数据会全部加载进内容。 二、SharedPreferences的简单使用 1.布局文件中,写入两个按钮,保存到SP,和从SP中获取数据 布局代码的文件就不再写了。 2.看MainActivity的代码,里面有注释详解 package com.example.spdemo; import

路宇的博客 1万+

Android入门第51天-使用AndroidSharedPreference存取信息

上一篇我们介绍了在android里如何读写本地文件。我们有一种场景,类似网页的cookie,要把用户的一些储如上一次登录、使用的痕迹等信息保存下来以便于每次不需要做重复“填表单”的操作,当在这种场景下我们如果也使用本地文件读写的话显然是“太重”了。因此android提供了一种轻量级存储叫SharedPreference专门用来存储这种场景下的数据。

打造全国最全的AI Agent开发知识领域的博客 1393

SharedPreference

SharedPreference复习笔记

肇秋贰拾捌的博客 1495

Android sharepreference槽点及改进方案

1 概述简介 1.1 简介 众所周知,SharedPreferences是一种轻型的Android数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。它的存储位置是在/data/data/<包名>/shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。比较经典的使用方式例如用户输入框对过往登录账户的存储。 1.2 使用方式 实现SharedPrefe

lzq520210的博客 3788

Android SharedPreference 详解

SharedPreferenceAndroid 提供的轻量级的,线程安全的数据存储机制,使用 key-value 键值对的方式将数据存储在 xml 文件中,存储路径为

HJXASLZYY的专栏 1679

Android SharedPreference详解

SharedPreferences作为一种数据持久化的方式,是处理简单的key-value类型数据时的首选。

轻口味的专栏 2199

Android开发--详解SharedPreference/PreferenceActivity

Android开发--详解SharedPreference/PreferenceActivity

yffhhffv的博客 330

Android连接手机时Shared,[android] sharedPreference入门详解

/********************2016年5月6日 更新**************************************/知乎:Android如何实现判断用户首次使用,比如首次使用时展示软件使用教程?面条:你需要的是SharedPreferencesSharedPreferences可以在本地存储一些简单的数据。首次进入的时候判断在本地存储的一个boolean值或者int值...

weixin_42509396的博客 383

Android中Context详解和获取SharedPreference

Context,中文直译为“上下文”,SDK中对其说明如下: Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It all...

weixin_33894640的博客 761

Android游戏开发十二】(保存游戏数据 [上文])详解SharedPreference 与 FIleInputS

Android游戏开发十二】(保存游戏数据[上文])详解SharedPreference 与FIleInputStream/FileOutputStream将数据存储到SD卡中!     Himi  原创, 欢迎转载,转载请在明显处注明! 谢谢。   原文地址: http://blog.csdn.net/xiaominghimi/archive/2011/01/02

namecyf的专栏 1094

Android游戏开发十二】(保存游戏数据 [上文])详解SharedPreference 与 FIleInputStream/FileOutputStream将数据存储到SD卡中!

对于游戏中的数据进行保存方式,在Android中常用的有四种保存方式,这里我先给大家统一先简单的介绍下: 1.  SharedPreference 此保存方式试用于简单数据的保存,文如其名属于配置性质的保存,不适合数据比较大的保存方式; 2. 文件存储 (FIleI

李天泉 248

Android游戏开发十二】详解SharedPreference 与 FIleInputStream/FileOutputStream将数据存储到SD卡中!...

本站文章均为李华明Himi原创,转载务必在明显处注明: 转载自【黑米GameDev街区】原文链接:http://www.himigame.com/android-game/327.html 对于游戏中的数据进行保存方式,在Android中常用的有四种保存方式,这里我先给大家统一先简单的介绍下: 1. SharedPreference ...

weixin_33739541的博客 77
上一篇: 安卓的事件分发的总结
下一篇: 安卓的基本的动画介绍
暖风清
博客等级 码龄10年 4粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值