SharedPreferences
Android轻量级数据存储
import android.content.Context;
import android.content.SharedPreferences;public class SharedPreferencesUtil {private SharedPreferences sharedPreferences;private SharedPreferences.Editor editor;public SharedPreferencesUtil(Context context, String fileName) {this.sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);this.editor = sharedPreferences.edit();}public void putString(String key, String value) {editor.putString(key, value);editor.apply(); //异步提交}public String getString(String key, String defaultValue) {return sharedPreferences.getString(key, defaultValue);}public void putInt(String key, int value) {editor.putInt(key, value);editor.apply();}public int getInt(String key, int defaultValue) {return sharedPreferences.getInt(key, defaultValue);}public void putBoolean(String key, boolean value) {editor.putBoolean(key, value);editor.apply();}public boolean getBoolean(String key, boolean defaultValue) {return sharedPreferences.getBoolean(key, defaultValue);}public void remove(String key) {editor.remove(key);editor.apply();}public void clear() {editor.clear();editor.apply();}
}
一个键值对保存的xml文件,存储在data/data/package/shared_prefs文件夹下
获取Sp的源码:
public SharedPreferences getSharedPreferences(String name, int mode) {if (mPackageInfo.getApplicationInfo().targetSdkVersion <Build.VERSION_CODES.KITKAT) {if (name == null) {name = "null";}}File file;synchronized (ContextImpl.class) {if (mSharedPrefsPaths == null) {mSharedPrefsPaths = new ArrayMap<>();}file = mSharedPrefsPaths.get(name);if (file == null) {file = getSharedPreferencesPath(name);mSharedPrefsPaths.put(name, file);}}return getSharedPreferences(file, mode);
}@Override
public SharedPreferences getSharedPreferences(File file, int mode) {SharedPreferencesImpl sp;synchronized (ContextImpl.class) {final ArrayMap<File, SharedPreferencesImpl> cache =getSharedPreferencesCacheLocked();sp = cache.get(file);if (sp == null) {checkMode(mode);sp = new SharedPreferencesImpl(file, mode);cache.put(file, sp);return sp;}}if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {sp.startReloadIfChangedUnexpectedly();}return sp;
}
SharedPreferences是个接口,其实现类是SharedPreferencesImpl,其构造方法如下:
SharedPreferencesImpl(File file, int mode) {mFile = file;mBackupFile = makeBackupFile(file);mMode = mode;mLoaded = false;mMap = null;mThrowable = null;startLoadFromDisk();
}
在startLoadFromDisk()中会从磁盘中加载xml文件,并将内容映射到mMap中
每次获取Sp对象时,都会把所有的存储数据从磁盘读取到内存,所以如果存储内容过多,会导致OOM
public String getString(String key, @Nullable String defValue) {synchronized (mLock) {awaitLoadedLocked();String v = (String)mMap.get(key);return v != null ? v : defValue;}}
从上面的代码可以看出,在调用getString()的时候加锁了,如果在主线程调用,意味着主线程被锁,如果此时Sp对象还未被获取,那么只有等Sp对象获取之后才能释放锁,这里可能会造成阻塞
public boolean commit() {long startTime = 0;MemoryCommitResult mcr = commitToMemory();SharedPreferencesImpl.this.enqueueDiskWrite(mcr, null /* 在当前线程同步写入 */);try {mcr.writtenToDiskLatch.await();} catch (InterruptedException e) {return false;} notifyListeners(mcr);return mcr.writeToDiskResult;
}
从上面代码可以看出commit()调用时,将内存中的Sp写入到磁盘,是个耗时操作,所以不要频繁的调用commit(),频繁的调用可能会导致ANR
public void apply() {final long startTime = System.currentTimeMillis();final MemoryCommitResult mcr = commitToMemory();final Runnable awaitCommit = new Runnable() {@Overridepublic void run() {try {mcr.writtenToDiskLatch.await();} catch (InterruptedException ignored) {}}};QueuedWork.addFinisher(awaitCommit);Runnable postWriteRunnable = new Runnable() {@Overridepublic void run() {awaitCommit.run();QueuedWork.removeFinisher(awaitCommit);}};SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable);notifyListeners(mcr);}
从上面的源码可以看出每次apply都会创建一个任务添加到 QueueWork中,如果频繁的执行写入操作,会造成ANR,
Android8.0之后优化,如果连续多次写入,只执行最后一次
Sp通过锁来保证线程安全,没有进程安全
文件备份机制
Sp在写入内容打磁盘时,会把原来的内容备份,写入成功后,会删掉备份内容
如果写入时发生异常,那么在下次启动时,如果有备份文件,会把备份文件作为源文件,未成功的文件删掉
相关文章:
SharedPreferences
Android轻量级数据存储 import android.content.Context; import android.content.SharedPreferences;public class SharedPreferencesUtil {private SharedPreferences sharedPreferences;private SharedPreferences.Editor editor;public SharedPreferencesUtil(Context con…...
服务(第二十五篇)redis的优化和持久化
持久化的功能:Redis是内存数据库,数据都是存储在内存中,为了避免服务器断电等原因导致Redis进程异常退出后数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;当下…...
David Silver Lecture 7: Policy Gradient
1 Introduction 1.1 Policy-Based Reinforcement Learning 1.2 Value-based and policy based RL 基于值的强化学习 在基于值的 RL 中,目标是找到一个最优的值函数,通常是 Q 函数或 V 函数。这些函数为给定的状态或状态-动作对分配一个值,表…...
知识图谱学习笔记——(五)知识图谱推理
一、知识学习 声明:知识学习中本文主体按照浙江大学陈华钧教授的《知识图谱》公开课讲义进行介绍,并个别地方加入了自己的注释和思考,希望大家尊重陈华钧教授的知识产权,在使用时加上出处。感谢陈华钧教授。 (一&…...
用vs2010编译和调试多个arx版本的arx项目
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、一级标题二级标题三级标题四级标题五级标题六级标题升级原先vs2008版本的项目文件到2010,或直接用vs2010新建一个arx项目; vs中查看项目属性:Project menu -> Properties,项目名上右…...
安全相关词汇
• DEW: Data Encryption Workshop • HSM: Hardware Security Module • KMS: Key Management System • KAM: Key Account Management • DHSM: Dedicated Hardware Security Module • KPS: Key Pair Service • CSMS: Cloud Secret Management Service • PCI-DSS: …...
最新入河排污口设置论证、水质影响预测与模拟、污水处理工艺分析及典型建设项目入河排污口方案报告书
随着水资源开发利用量不断增大,全国废污水排放量与日俱增,部分河段已远远超出水域纳污能力。近年来,部分沿岸入河排污口设置不合理,超标排污、未经同意私设排污口等问题逐步显现,已威胁到供水安全、水环境安全和水生态安全&#x…...
2023年认证杯二阶段C题数据合并python以及matlab多途径实现代码
对于每种心率下给出的数据,我们需要进行合并才能方便后续处理,这里为大家展示利用python以及matlab分别实现合并的代码 import pandas as pd import os# 创建一个空的DataFrame对象 merged_data pd.DataFrame()# 设置数据文件所在的文件夹路径 folder_…...
Win11校园网不弹出登录页面怎么回事?
Win11校园网不弹出登录页面怎么回事?最近有用户在使用校园网的时候遇到了一些问题,访问登录网站的时候,一直无法显示登录的界面。那么遇到这个情况如何去进行解决呢?一起来看看以下的解决方法分享吧。 解决方法如下: 方…...
S32K144低功耗休眠与唤醒实践总结
在做车载项目时,模块在常供电时需要维系随时可以被唤醒工作的状态,并且静态电流需要在3mA以内,当然在JTT1163标准中要求的是5mA以内。 目标明确了,在模块休眠时需要关闭一切不必要的资源消耗,只保留模块被唤醒的部分功…...
一文吃透 Vue 框架教程(上)
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
堆排序与取topK java实现
1.堆排序思路 最近趁着有点时间,稍微复习了一下数据结构相关内容,温习了一下堆排序,做一下记录。 首先我们复习一下什么是堆: 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,…...
https通信流程通俗理解
场景,假设A和B进行通信 CA: ( Certificate Authority )就是颁发 HTTPS 证书的组织。 通信流程步骤: 1、A告诉B使用 RSA算法进行加密,B说好的。 2、A和B同时用 RSA算法各自生成一对公钥密钥,各自的公钥密钥都不同。 3…...
银行零售业务转型方法论:打造数字化的“有机体”
传统的业务增长进度叫做连续性创新,它是在一条曲线上渐进性的改良和发展,但这种发展终有极限,如果不能及时开辟第二增长曲线,就很容易被时代所抛弃。过去十年,以互联网为代表的数字化转型的先行者,不断冲击…...
【STM32】STM32使用RFID读卡器
STM32使用RFID读卡器 RFID卡片 ID卡(身份标识):作用就是比如你要输入学号,你刷卡直接就相当于输入学号,省去了输入的过程 IC卡:集成电路卡,是将一种微电子芯片嵌入卡片之中 RFID的操作 1、…...
spring集成mybatis的原理
spring是怎样和mybatis继承的? 在idea里点mapper.queryOne()直接跳到了接口或xml,它究竟是怎样利用jdbc执行的? 我直接调用mapper.queryOne是怎么使用的sqlsession?怎么去connect的? mybatis是怎样根据mapper找到对应的…...
限速神器RateLimiter源码解析 | 京东云技术团队
作者:京东科技 李玉亮 目录指引 限流场景 软件系统中一般有两种场景会用到限流: •场景一、高并发的用户端场景。 尤其是C端系统,经常面对海量用户请求,如不做限流,遇到瞬间高并发的场景,则可能压垮系统…...
spring中怎样优化第三方bean?
需求:将数据库连接四要素提取到properties配置文件,spring来加载配置信息并使用这些信息来完成属性注入。第三方bean属性优化的思路如下: 1.在resources下创建一个jdbc.properties(文件的名称可以任意) 2.将数据库连接四要素配置到配置文件中 3.在Spr…...
8分钟的面试,我直呼太变态了......
干了两年外包,本来想出来正儿八经找个互联网公司上班,没想到算法死在另一家厂子。 自从加入这家外包公司,每天都在加班,钱倒是给的不少,所以也就忍了。没想到11月一纸通知,所有人不许加班,薪资…...
别去外包,干了3年,彻底废了......
先说一下自己的情况。大专生,19年通过校招进入湖南某软件公司,干了接近3年的测试,今年年上旬,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了三年,…...
DeepSeek RAG系统渗透测试全链路复现(含PoC代码与防御加固清单)
更多请点击: https://kaifayun.com 第一章:DeepSeek RAG系统渗透测试全链路复现概览 DeepSeek RAG系统作为面向企业级知识检索增强生成的典型架构,其安全边界不仅涵盖LLM服务层,更延伸至向量数据库、检索代理、提示工程网关及外部…...
别再让模型在Unity里‘抽风’了!Blender导出FBX到Unity的7步避坑自查清单
别再让模型在Unity里‘抽风’了!Blender导出FBX到Unity的7步避坑自查清单当你花了三天三夜精心雕琢的Blender模型,导入Unity后却变成了一团旋转错乱、贴图闪烁的"抽象艺术",那种崩溃感每个3D开发者都懂。本文将用实战经验帮你建立一…...
自制BLE112串口编程器:基于Bootloader的免调试器烧录方案
1. 项目概述:为BLE112模块打造一款免调试器的RS232编程器在嵌入式开发,特别是早期的蓝牙低功耗(BLE)模块应用中,我们常常会遇到一个棘手的问题:官方开发工具链的依赖和限制。以Silicon Labs(当时…...
ARM架构CONSTRAINED UNPREDICTABLE行为解析与应对
1. ARM架构中的CONSTRAINED UNPREDICTABLE行为解析在处理器架构设计中,UNPREDICTABLE行为通常指架构规范未明确定义的执行结果,可能导致不可预期的系统状态。ARM架构通过引入CONSTRAINED UNPREDICTABLE机制,将这类行为限制在特定范围内&#…...
为什么软件开发偏爱 Linux?深度剖析 Linux 相较于 Windows 的核心优势
引言 在软件开发的世界里,一个有趣的现象是:无论是大型互联网公司的服务器集群,还是资深程序员的个人开发机,Linux 操作系统的身影无处不在。与之形成鲜明对比的是,尽管 Windows 在个人消费市场占据绝对主导地位&…...
AI圈神秘领袖Ilya一幅画引爆全网,OpenAI三件大事暗示AGI时代将至?
AI圈神秘精神领袖Ilya在Instagram上传一幅画引发疯狂解读,与此同时,OpenAI连续公布数学成果、升级Codex、筹备IPO,释放AGI到来的强烈信号。Ilya画作引猜测Ilya上传的画中,罗丹的「思考者」踩在芯片Die Shot上,右下角签…...
对比自行维护多个 API 源,使用 Taotoken 聚合服务在运维复杂度上的降低
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比自行维护多个 API 源,使用 Taotoken 聚合服务在运维复杂度上的降低 在构建依赖多个大语言模型的应用时,…...
JWT弱密钥爆破实战:从HS256签名原理到CTF权限提升
1. 这不是密码学考试,而是一场“密钥猜谜”实战JWT(JSON Web Token)在现代Web系统中早已不是可选项,而是默认配置。登录成功后返回一串形如eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMjMsIm5hbWUiOiLnlKjliYkiLCJpYX…...
抖音内容批量下载实战:从零开始构建个人视频资料库
抖音内容批量下载实战:从零开始构建个人视频资料库 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support.…...
VisualCppRedist AIO:Windows系统依赖问题终极解决方案,一键修复所有VC++运行库
VisualCppRedist AIO:Windows系统依赖问题终极解决方案,一键修复所有VC运行库 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经…...
