安卓SharedPreference的详解及总结

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

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

相关推荐

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

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

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

SharedPreference

SharedPreference复习笔记

肇秋贰拾捌的博客 1502

Android 中SharedPreferences的详解

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

路宇的博客 1万+

Android sharepreference槽点及改进方案

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

lzq520210的博客 3796

图像调整亮度饱和度 c语言,【C#/WPF】调节图像的HSL(色相、饱和度、明亮度)...

先说概念:HSL是一种描述颜色的方式(其他颜色描述方式还有大家熟悉的RGB值)。HSL三个字母分别表示图像的Hue色相、Saturation饱和度、Lightness明亮度。需求:制作一个面板,包含三个滑动条,拖动滑动条可以修改目标图片的HSL值。即模仿PS中类似的功能,如下图:方案一:遍历所有像素点,修改每个点的HSL值。前台界面:一个Image控件显示目标图片,一个Button按钮点击一下降低...

weixin_39935777的博客 1155

【STM32-DSP库的使用】基于Keil5 + STM32CubeMX + CMSIS-DSP 手动添加、库添加方式

CMSIS-DSP库在工程中应用遇到的所有问题进行归纳终结

洋洋的博客 1万+

Android SharedPreference 详解

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

HJXASLZYY的专栏 1687

无人自行车平衡控制:最小二乘法动态零点拟合实践

本文探讨了无人自行车平衡控制中动态零点的重要性及实现方法。通过最小二乘法拟合车头角度与ROL值的线性关系,解决了固定零点在转向时导致的稳定性问题。实践表明,动态零点拟合能显著提升系统平衡稳定性并降低能耗。

uran的专栏 660

Android SharedPreference详解

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

轻口味的专栏 2212

SPECweb2009调优指南

 SPECweb2009 是衡量 Web 服务器性能和能效的标准化基准,可以对 Web 服务器的并发数进行性能测试,评测 Web 服务器能够支持的最大同时连接数的客户端/服务器(每秒能够响应的最大请求数)。为充分利用服务器性能,提升SPECweb2009测试结果,可通过增大系统进程数、优化服务器软件参数、绑核以及优化参数等。

developersupport的博客 2607

基于openwrt平台搭建局域网技术验证之四

1、测试目的 验证l2tp客户端模式的可行性。 提供vpn-l2tp模式的客户端功能。 2、参考资料 参考链接1:https://www.lucktang.com/191.html 3、测试过程 测试过程需要用到的资源: 路由器俩个 win7系统电脑俩台 ③ 交换机一个 ④ 网线三根 测试组网如下图所示: 组网说明: R0公司路由器 S1 交换机 R1 路由器1 R2 路由器2 PC1 个人电脑1 PC2 个人电脑2 (R0) lan口接(S1)...

caofengtao1314的专栏 1960

Android开发--详解SharedPreference/PreferenceActivity

Android开发--详解SharedPreference/PreferenceActivity

yffhhffv的博客 332

TruckSim与Simulink联合仿真中的车轮转角精确控制策略

本文深入探讨了TruckSim与Simulink联合仿真中实现车轮转角精确控制的关键策略。针对多轴车辆路径跟踪时转角指令失灵的常见问题,核心在于正确配置TruckSim转向轴的外部输入模式(Advanced Settings),并确保仿真接口的稳定搭建。文章详细解析了从单轴到多轴协同转向的配置方法,并提供了提升MPC路径跟踪精度的实战技巧与调试经验。

weixin_29035147的博客 367

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

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

weixin_42509396的博客 385

信号处理算法:离散余弦变换(DCT)_(1).离散余弦变换(DCT)概述

离散余弦变换的数学定义如下:对于一个长度为NNN的离散信号xnx(n)xn,其DCT变换后的系数XkX(k)XkXk∑n0N−1xncos⁡πNn12kk012N−1Xkn0∑N−1​xncosNπ​n21​kk012N−1其中,kkk是频率指数,nnn是时间或空间索引。离散余弦变换(DCT)是一种强大的信号处理技术,广泛应用于图像压缩、音频处理、数据压缩等领域。

2401_87715305的博客 1554

2024年11月架构设计师案例分析真题回顾,附参考答案、解析及所涉知识点(二)

软考高级系统架构设计师考试包含三个科目:信息系统综合知识、案例分析和系统架构设计论文。考试形式为机考。本文主要回顾2024年下半年(2024-11-10)系统架构设计师考试上午第二科案例分析的题目,同时附带参考解答、解析和所涉知识点。

一几文的编程学习笔记。 1661

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的博客 766

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

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

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

namecyf的专栏 1097

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

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

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

李天泉 250

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

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

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

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值