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

【Android】SharePreference原理

一,概述

SharePreference作为轻量级应用偏好持久化存储API,可以简单存储一些key-value值,其实现是基于file系统,在应用data/xxx/shared_prefs路径下,保存了xml文件,而实现存储。本文,基于SharePreference的基本使用,到其内部实现,做一个简单介绍。

二,简例

key-value api如下

//1,从context中获得SharePreference实现类实例SharedPreferences sharedPreferences = context.getSharedPreferences("share_name", Context.MODE_PRIVATE);//2,read 方法boolean value1 = sharedPreferences.getBoolean("key1", false);float value2 = sharedPreferences.getFloat("key2", 1f);int value3 = sharedPreferences.getInt("key3", 1);long value4 = sharedPreferences.getLong("key4", 1L);String value5 = sharedPreferences.getString("key5", "default");Set<String> value6 = sharedPreferences.getStringSet("key6", Collections.emptySet());//3,write方法SharedPreferences.Editor edit = sharedPreferences.edit();edit.putBoolean("key1",false);edit.putFloat("key1",1f);edit.putInt("key1",1);edit.putLong("key1",1L);edit.putString("key1","false");edit.putStringSet("key1",Collections.emptySet());//提交,commit同步sync,apply是async,不阻塞当前线程edit.commit();edit.apply();

创建flag以下可选

MODE_PREVATE:私有,其它应用不可读取

MODE_WORLD_READABLE,其它应用只可读取

MODE_WORLD_WRITEABLE,其它应用可写可读

MODE_MULTI_PROCESS,已弃用,代表多进程相关

三,实现

1,初始化

context.getSharePreference(String name,int flags)方法返回一个SharePreferenceImpl,其实现在ContextImpl中,

1,创建一个ArrayMap,存储name与file路径的映射

2,返回name对应的本地路径

getPreferencesDir()方法返回/data/xxx/shared_prefs路径,随后创建一个name.xml的file

3,返回一个SharePreferenceImpl,跟进

1,2,Sp与File的缓存

3,多进程FLAG相关,

跟进SharePreferenceImpl实现类,

构造方法中创建了一个file的备份,并通过startLoadFromDisk异步加载磁盘内容到内存中,

使用的线程池参数如下,最大线程数1,核心线程数0,存活10s,

跟进loadFromDisk

1,备份文件存在,使用备份文件加载,并且重命名为主文件。此举在于SharePreference未保存发生错误时,可以恢复数据而不至于丢失。

2,文件可读,

3,读取对应xml文件,并且通过XmlUtils.readMapXml解析,并保存至mMap中,

此处,可以看下应用中存储的file,内容如下,

2,read

随便看一个getString方法,

通过mLock加锁,再从mMap中取值,跟进awaitLoadedLocked方法

mLoaded在初始化完毕后,才为true,因此此处相当于等待loadFromDisk任务完成,通过mLock.notifyAll方法通知到此处,

3,write

以putWrite为例

加载完毕后,直接返回一个EditorImpl,跟进

以上,将write事件全写进mModified map中,通过commit或apply再写入磁盘,以减少io次数,

跟进commit

1,通过commitToMemory,返回一个MemoryCommitResult,可以理解一次写事务,内部是通过mModified更新mMap,并保存至mapToWriteToDisk中,如下,

2,将写事务加入队列中执行,

以上,创建一个writeRunnable,将mcr传入,并且加入队列,

3,等待写入CountLaunch

以上,io如果ok,则down一次。

4,通知Observers

注意,其IO操作进入QueueWork队列,在如下线程操作,

看下apply

不同点在于是否在当前线程执行Condition#await

以上,创建一个postWriteRunnable,此runnable即await一次,执行时机移至writeToFile后,

将await时机延后&执行线程更换至子线程,避免Queue排队以及io时阻塞当前线程,执行io线程同commit,仍在"queued-work-looper"而writeToFile时已经将Count计数归0,postWriteRunnable不会阻塞。

http://www.xdnf.cn/news/648757.html

相关文章:

  • 【ARTS】【LeetCode-59】螺旋矩阵
  • 【HarmonyOS 5应用架构详解】深入理解应用程序包与多Module设计机制
  • 深度解析 8086 处理器:x86 架构的奠基者
  • 【后端高阶面经:架构篇】46、分布式架构:如何应对高并发的用户请求
  • 2025社区团购系统开发:未来趋势、核心技术与落地解决方案
  • Python - 文件部分
  • 【React】- React-RND 深度使用指南:实现自由拖拽、避坑受控陷阱!
  • Hadoop架构与核心模块解析
  • 【每日渲美学】3ds Max橱柜材质教程:厨房高光烤漆、木纹、亚克力、亚光板材渲染优化指南
  • 洪水危险性评价与风险防控全攻略:从HEC-RAS数值模拟到ArcGIS水文分析,一键式自动化工具实战,助力防洪减灾与应急管理
  • 探索数据结构之顺序表:从入门到精通
  • 「读书报告」Spark实时大数据分析
  • 数据结构-图的应用,实现环形校验和拓扑排序
  • redis五种数据结构详解(java实现对应的案例)
  • 高阶数据结构——哈希表的实现
  • Elasticsearch 节点角色详解及协调节点请求策略
  • FFmpeg 4.3 H265 二十二.2,在网络环境RTSP中,断线下如何处理
  • Oracle NLS_LANG 常见问题
  • sqli-labs第二十八关——Trick with ‘union select‘
  • Flink Checkpoint SavePoint 深度剖析与工程实践
  • 在Spring Boot中实现Kafka动态反序列化:针对多主题的灵活数据处理
  • 网络安全-等级保护(等保) 3-2-2 GB/T 28449-2019 第7章 现场测评活动/第8章 报告编制活动
  • JVM GC 分类与原理深度解析
  • 10:图像传参+UI界面互传
  • JAVA Apache POI实战:从基础Excel导出入门到高级功能拓展
  • 网络安全全知识图谱:威胁、防护、管理与发展趋势详解
  • 二、网络安全常见编码及算法-(2)
  • 联邦学习与数据隐私保护之间的联系
  • 《Stable Diffusion 3.0企业级落地指南》——技术赋能与商业价值的深度融合实践
  • 数字电子技术基础(六十四)——只读存储器