Android之SharedPreferences内部原理浅析
SharedPreferences内部工作原理:
1、调用getSharedPreferences();创建一个SharedPreferences对象,其中会先判断是否存在对应xml文件,如果发现存在则会有一个预加载操作,这个操作是把xml文件的内容通过I/O操作和XmlUitl解析后存入一个map对象中,所以我们调用SharedPreferences::getString();等get操作实际上是不会对文件做I/O操作,而是直接访问刚刚的map集合的内容,这提高了效率,如果对应的xml不存在则重新创建一个对应的xml文件。
部分实现如下:
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
SharedPreferencesImpl sp;
//...
sp = packagePrefs.get(name);
if (sp == null) {
File prefsFile = getSharedPrefsFile(name);
//该构造方法会调用startLoadFromDisk();把数据从硬盘加载到内存
sp = new SharedPreferencesImpl(prefsFile, mode);
packagePrefs.put(name, sp);
return sp;
}
//...
return sp;
}
2、put写操作:写操作也有两步,一是把数据先写入内存中,即map集合,二是把数据写入硬盘文件中。这样才能保证数据的完整性,写操作有两个提交的方式:
commit():线程安全,性能慢,一般来说在当前线程完成写文件操作
apply():线程不安全,性能高,异步处理IO操作,一定会把这个写文件操作放入一个SingleThreadExecutor线程池中处理
3、SharedPreferences在第一次创建后会一直维持一个Singleton,每次调用getSharedPreferences()都返回唯一的一个实例
SharedPreferences a = getSharedPreferences("test",0);
SharedPreferences b = getSharedPreferences("test",0);
SharedPreferences c = getSharedPreferences("test",0);
Log.i(TAG, "result: "+(a==b)+","+(b==c));
//12-04 13:38:17.811 2287-2287/com.sunzxy.myapplication I/MainActivity: result: true,true
SharedPreferences使用封装:
由于SharedPreferences的key与value其实最终都是以String类型存在,所以可以这样写一个SharedPreferences工具类:
/**
* Created by Sunzxyong on 15/12/4.
*/
public class PerferenceManager {
private static final String PERF_NAME = "com.suznxyong.util.my_perf";
private static final int CURRENT_VERSION_CODE = 1;
private volatile static PerferenceManager instance;
private final SharedPreferences preferences;
private PerferenceManager(Context context) {
preferences = context.getSharedPreferences(PERF_NAME, Context.MODE_PRIVATE);
checkPrefVersion();
}
public static PerferenceManager getInstance(Context context) {
if (instance == null) {
synchronized (PerferenceManager.class) {
if (instance == null)
instance = new PerferenceManager(context);
}
}
return instance;
}
public final void putValue(String key, String value) {
preferences.edit().putString(key, value).apply();
}
public final String getValue(String key) {
checkIsLegal(key);
return preferences.getString(key, "");
}
public final void deleteValue(String key) {
checkIsLegal(key);
preferences.edit().remove(key).apply();
}
public final void clear() {
preferences.edit().clear().apply();
}
private void checkIsLegal(String key) {
if (TextUtils.isEmpty(key))
throw new IllegalArgumentException("This parameter is illegal,key : " + key);
}
private void checkPrefVersion() {
final int oldVersion = preferences.getInt(PERF_NAME, 0);
if (oldVersion < CURRENT_VERSION_CODE) {
preferences.edit()
.clear()
.putInt(PERF_NAME, CURRENT_VERSION_CODE).apply();
}
}
}
由于应用版本升级时并不会删除SharedPreferences文件,所以可以加个版本判断,来进行一些数据更新,从上面看来,由于每一次调用getSharedPreferences()都会有IO操作,当内容比较多时,那么就不适宜在Application的onCreate中进行SharedPreferences文件初始化了,最好的办法是开个子线程去完成它的创建和数据的预加载!!!
Android之SharedPreferences内部原理浅析的更多相关文章
- Git内部原理浅析
Git独特之处 Git是一个分布式版本控制系统,首先分布式意味着Git不仅仅在服务端有远程仓库,同时会在本地也保留一个完整的本地仓库(.git/文件夹),这种分布式让Git拥有下面几个特点: 1.直接 ...
- Android自动化测试框架UIAutomator原理浅析
UIAutomator是一个Android自动化测试框架,是谷歌在Android4.1版本发布时推出的一款用Java编写的UI测试框架,它只能用于UI即黑盒方面的测试.所以UIAutomator只能运 ...
- Android线程管理(三)——Thread类的内部原理、休眠及唤醒
线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...
- jQuery内部原理和实现方式浅析
这篇文章主要介绍了jQuery内部原理和实现方式浅析,本文试图从整体来阐述一下jQuery的内部实现,需要的朋友可以参考下 这段时间在学习研究jQuery源码,受益于jQuery日益发展强大,研究jQ ...
- Android线程管理(三)——Thread类的内部原理、休眠及唤醒
线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...
- Android启动篇 — init原理(二)
======================================================== ================================== ...
- Android热修复技术原理详解(最新最全版本)
本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...
- Android FoldingLayout 折叠布局 原理及实现(二)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/44283093,本文出自:[张鸿洋的博客] 1.概述 在上一篇Android Fo ...
- JVM 内部原理(四)— 基本概念之 JVM 结构
JVM 内部原理(四)- 基本概念之 JVM 结构 介绍 版本:Java SE 7 每位使用 Java 的程序员都知道 Java 字节码在 Java 运行时(JRE - Java Runtime En ...
随机推荐
- 360面试-C++后端(实习)
在线远程视频面试 一面: 自我介绍. 知道哪几种排序算法,各算法的时间复杂度. 解决hash冲突的几种方式. 有哪些方法清除cache中旧的数据.不太清楚,我扯到了操作系统中缺页中断的页面置换原理上, ...
- js 在iframe子页面获取父页面元素,或在父页面 获取iframe子页面的元素的几种方式
用JS或jquery访问页面内的iframe,兼容IE/FF 注意:框架内的页面是不能跨域的! 假设有两个页面,在相同域下. index.html 文件内含有一个iframe: XML/HTML代码 ...
- 京东消息中间件JMQ
http://blog.csdn.net/javahongxi/article/details/54411464 [京东技术]京东的MQ经历了JQ->AMQ->JMQ的发展,其中JQ的基于 ...
- Red Hat Enterprise Linux7的安装与oracle 12c的安装
Red Hat Enterprise Linux7的安装与oracle 12c的安装 本文档中用到的所有参数均位于文末附录 Red Hat Enterprise Linux7的安装 新建完虚拟机后,挂 ...
- 下拉框多级联动辅助js,优化您的下拉框
function IniteSelect(options) { $("body").IniteSelect(options) } (function ($) { $.fn.Init ...
- 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- CustomYieldInstruction 自定义中断指令
ActionScript3脚本引擎为了方便热更新逻辑开发,提供的从脚本继承Unity类库功能在一些情况下可以提供开发的便利. 这次来建立一个示例,演示一下如何在脚本中自定义协程中断指令 Unity中的 ...
- Bootstrap3 表格-响应式表格
将任何 .table 元素包裹在 .table-responsive 元素内,即可创建响应式表格,其会在小屏幕设备上(小于768px)水平滚动.当屏幕大于 768px 宽度时,水平滚动条消失. Fir ...
- 我为什么放弃使用MyBatis3的Mapper注解
最近在使用MyBatis3做项目.在使用注解实现Mapper的时候遇到了比较奇葩的问题:在实现数据的batch insert的时候总是报错.好不容易可以正常插入了,但是又不能返回自增的主键id到实体b ...
- Eclipse的Debug调试技巧
作为开发人员,掌握开发环境下的调试技巧十分有必要.我们在编写java程序的过程中,经常会遇到各种莫名其妙的问题,为了检测程序是哪里出现问题,经常需要增加日志,看变量的值,这样调试很麻烦.假设我每天花费 ...
- arm-none-eabi-g++ -Xlinker -T "../LF3Kmonitor.ld" -Xlinker -Map="Bogota_ICT_V.map"-ram-hosted.ld -mc
1.arm-none-eabi-g++:是编译ARM裸板用的编译器,不依赖于操作系统. 2.-Xlinker -T "../LF3Kmonitor.ld" -Xlinker -Ma ...