当前位置: 首页 > news >正文

Adnroid 数据存储:SharedPreferences详解【SharedPreferencesUtils,SharedPreferences的ANR】

目录

1)SP是什么、如何使用,SPUtils
2)SP的流程
3)comit和apply

一、SP是什么,如何使用,SPUtils


1.1 SP是什么?

SharedPreferences是Android平台提供的一种轻量级的数据存储方式,用于保存和读取应用程序的配置信息或其他简单的键值对数据。

使用SharedPreferences有以下几个优点:

  1. 简单易用:SharedPreferences提供了简单的API来保存和读取数据,无需编写复杂的数据库操作代码。
  2. 轻量级:相比于SQLite数据库等其他数据存储方式,SharedPreferences更加轻量级,适合存储少量的配置信息或用户偏好设置。
  3. 高效快速:由于数据存储在内部存储空间中,访问速度较快,适合存储需要频繁读取的数据。
  4. 跨进程共享:SharedPreferences可以被多个组件或进程共享访问,方便不同组件之间的数据交互和共享配置信息。
  5. 自动持久化:SharedPreferences会自动将数据持久化到磁盘上,即使应用关闭后再次启动也能保留之前的数据。

1.2 SP如何使用?

  1. 获取SharedPreferences实例:
val sharedPreferences = context.getSharedPreferences("my_preferences", Context.MODE_PRIVATE)
  1. 读取数据:
使用getString()方法读取String类型的值:val value = sharedPreferences.getString("key", "default_value")使用getInt()方法读取Int类型的值:val value = sharedPreferences.getInt("key", default_value)
  1. 写入数据:
使用edit()方法获取SharedPreferences.Editor实例:val editor = sharedPreferences.edit()
使用putString()方法写入String类型的值:editor.putString("key", "value")
使用putInt()方法写入Int类型的值:editor.putInt("key", value)
  1. 提交或应用更改:
使用commit()方法提交更改:editor.commit()使用apply()方法应用更改(异步操作):editor.apply()

1.3 SPUtils

public class SharedPreferencesUtils {/*** 保存在手机里面的文件名*/private static final String FILE_NAME = "share_date";/*** 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法* @param key* @param object*/public static void setParam(String key, Object object){String type = object.getClass().getSimpleName();SharedPreferences sp = MyApplication.getContext().getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);SharedPreferences.Editor editor = sp.edit();if("String".equals(type)){editor.putString(key, (String)object);}else if("Integer".equals(type)){editor.putInt(key, (Integer)object);}else if("Boolean".equals(type)){editor.putBoolean(key, (Boolean)object);}else if("Float".equals(type)){editor.putFloat(key, (Float)object);}else if("Long".equals(type)){editor.putLong(key, (Long)object);}editor.commit();}/*** 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值* @param key* @param defaultObject* @return*/public static Object getParam(String key, Object defaultObject){String type = defaultObject.getClass().getSimpleName();SharedPreferences sp = MyApplication.getContext().getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);if("String".equals(type)){return sp.getString(key, (String)defaultObject);}else if("Integer".equals(type)){return sp.getInt(key, (Integer)defaultObject);}else if("Boolean".equals(type)){return sp.getBoolean(key, (Boolean)defaultObject);}else if("Float".equals(type)){return sp.getFloat(key, (Float)defaultObject);}else if("Long".equals(type)){return sp.getLong(key, (Long)defaultObject);}return null;}}

二、SP的流程


1)首先SP使用的是xml格式保存数据(如下图),文件位于应用的私有存储空间中【在/data/data/<package_name>/shared_prefs/目录下】。

2) SharedPreferences在读取xml文件时,会把整个xml文件加载到内存中,并以DOM的形式进行解析。

3)当新增一个K-V时,写入磁盘是全量更新,即会把之前的文件再次更新一遍。这意味着如果我们有100个数据,
如果只更新一项数据,也需要将所有数据转化成xml格式,然后再通过io写入文件中,这也就是导致使用SP可能存在ANR的情况出现。

在这里插入图片描述

三、comit和apply


SharedPreferences的commit()和apply()方法都用于提交对数据的修改

commit()方法:

    commit()方法是同步地将修改集合中的数据写入磁盘。它会阻塞当前线程直到写入操作完成,并返回一个boolean值表示是否成功。如果写入过程中发生异常或失败,commit()方法会抛出异常并返回false

对于SharedPreferences的commit()方法,由于它是同步的,会在主线程中执行写入操作。如果数据量较大或者磁盘IO速度较慢,可能会导致阻塞主线程,从而引发ANR错误。

apply()方法:

    apply()方法是异步将修改集合中的数据写入磁盘。它不会阻塞当前线程,而是立即返回。写入在后台线程中进行,因此不会影响主线程的执行。apply()方法没有返回值,也不会抛出异常,所以无法知道写入操作是否成功。

不过,apply也会导致ANR问题,具体可以看上面的源码, apply 其实利用了CountDownLatch机制,阻塞了当前线程,后续 Activity 的onStop()中会将这里的awaitCommit取出来执行,即UI线程会阻塞等待sp文件写入磁盘,为什么等待?为了保证异步任务及时完成。所以我们有的时候可以看到退出一个页面的时候,感觉也会卡,因为阻塞了主线程。

总结:SP,不能存储太多的信息,或者按分类去加载存储,很小很简单的数据可以保存到SP里面。

http://www.lryc.cn/news/419491.html

相关文章:

  • Sentinel 规则持久化到 Nacos 实战
  • 服务器CPU天梯图2024年8月,含EYPC/至强及E3/E5
  • SpringBoot加载dll文件示例
  • 9.C基础_指针与数组
  • C语言——结构体与共用体
  • vs+qt项目转qt creator
  • 微信小程序 checkbox 实现双向绑定以及特殊交互处理
  • 我在高职教STM32——I2C通信之读写EEPROM(1)
  • 【ARM】应用ArmDS移植最小FreeRTOS系统
  • golang下载、上传文件MD5高效计算方法,利用io.TeeReader函数特性 实时计算文件md5签名
  • TreeMap实现根据值比较
  • 2024前端面试(内容持续更新)
  • 接口基础知识5:详解request headers(一篇讲完常见字段)
  • mac的node使用
  • HTML - 简易版打字练习
  • 【生成式人工智能-四-chatgpt的训练过程-pretrain预训练自督导式学习督导式学习】
  • 期权价格的奥秘:深入理解影响因素
  • STM32-USART时序与寄存器状态分析
  • 从零安装pytorch并在pycharm中使用
  • 开源AI工具FastGPT和RagFlow对比
  • 第N2周:NLP中的数据集构建
  • AI助力浮雕创作!万物皆可浮雕?Stable Diffusion AI绘画【浮雕艺术】之文生浮雕!
  • 你觉得大模型时代该出现什么?
  • JS【详解】事件委托
  • 谈对象系列:C++类和对象
  • 设计模式20-备忘录模式
  • 绘制echarts-liquidfill水球图
  • 应急响应:D盾的简单使用.
  • c语言第14天笔记
  • 服装行业QMS中的来料检验:常见问题解析与解决策略