Android SharedPreference最佳实践
Android提供多种方式保存应用数据,其中一种方式是SharedPreferences,使用键值对保存私有基本的数据。所有的逻辑仅基于以下三个类:
SharedPreference
SharedPreference在这三个类是最重要的,负责获取(解析)存储数据。提供获取对象的编辑接口,在OnSharedPreferenceChangeListener中提供增加移出对象的接口。
- 创建SharedPreference对象,需要上下文对象(可以是应用程序的上下文)。
- getSharedPreferences 方法解析配置文件并创建相关的对象映射。
- 通过上下文有多种创建它,强烈建议使用MODE_PRIVATE。因为创建一个可读写的文件是非常危险的,容易在应用中产生安全漏洞。
// parse Preference file
SharedPreferences preferences = context.getSharedPreferences("<span class="skimlinks-unlinked">com.example.app", Context.MODE_PRIVATE); // get values from Map
preferences.getBoolean("key", defaultValue)
preferences.get..("key", defaultValue) // you can get all Map but be careful you must not modify the collection returned by this
// method, or alter any of its contents.
Map<String, ?> all = preferences.getAll(); // get Editor object
SharedPreferences.Editor editor = preferences.edit(); //add on Change Listener
preferences.registerOnSharedPreferenceChangeListener(mListener); //remove on Change Listener
preferences.unregisterOnSharedPreferenceChangeListener(mListener); // listener example
SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener
=newSharedPreferences.OnSharedPreferenceChangeListener() {
@Override
publicvoidonSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
};
Editor
SharedPreferences.Editor是用来修改SharedPreferences对象值的接口。你在editor 做出的修改都是待处理的,并没有被复制到SharedPreferences里,直到你调用commit()或apply()修改才会被执行。
- 使用简单的接口在Editor放入值。
- 同步保存数据使用commit() 方法或者异步保存数据使用apply()方法会更快点。实际上不同的线程使用commit()会更快点,这是我喜欢使用commit()方法的原因。
- 移出数据使用remove()方法,清除所有数据使用clear()方法。
// get Editor object
SharedPreferences.Editor editor = preferences.edit(); // put values in editor
editor.putBoolean("key", value);
editor.put..("key", value); // remove single value by key
editor.remove("key"); // remove all values
editor.clear(); // commit your putted values to the SharedPreferences object synchronously
// returns true if success
booleanresult = editor.commit(); // do the same as commit() but asynchronously (faster but not safely)
// returns nothing
editor.apply();
性能和注意事项
SharedPreferences是单例对象,你可以很容易获取你想要的引用。只在你第一次调用getSharedPreferences方法时打开文件时,创建一个实例对象。
// There are 1000 String values in preferences
SharedPreferences first = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 4 milliseconds SharedPreferences second = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 0 milliseconds SharedPreferences third = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 0 milliseconds
SharedPreferences 是单例对象,你可以改变它的实例,不用担心同一个对象数据会不同。
first.edit().putInt(”key”,).commit();
intfirstValue = first.getInt(”key”,));
// firstValue is 15
intsecondValue = second.getInt(”key”,));
// secondValue is also 15
当你第一次调用get方法时,它解析对象并把放入map中,第二次获取数据从map 中获取,不需再解析。
first.getString(”key”,null)
// call time = 147 milliseconds first.getString(”key”,null)
// call time = 0 milliseconds second.getString(”key”,null)
// call time = 0 milliseconds third.getString(”key”,null)
// call time = 0 milliseconds
记住Preference的数据越大,get、commit、apply、remove和clear方法耗时越长。所以强烈建议把存储的数据分成小的对象。
当你的应用更新以后,你的Preferences不会被移除。所以有些情况下需要创建迁移数据的方案。比如,在应用启动的时候,你的应用解析本地JSON数据,实现这个你需要做的仅仅是存储标志数据(该数据是否为本地数据)。一段时间后,你更新JSON数据发布新的版本,用户会更新应用程序但是不会下载新的JSON数据,因为已经在本地存储了。
publicclassMigrationManager {
privatefinalstaticString KEY_PREFERENCES_VERSION ="key_preferences_version";
privatefinalstaticintPREFERENCES_VERSION =;
publicstaticvoidmigrate(Context context) {
SharedPreferences preferences = context.getSharedPreferences("pref", Context.MODE_PRIVATE);
checkPreferences(preferences);
}
privatestaticvoidcheckPreferences(SharedPreferences thePreferences) {
finaldoubleoldVersion = thePreferences.getInt(KEY_PREFERENCES_VERSION,);
if(oldVersion < PREFERENCES_VERSION) {
finalSharedPreferences.Editor edit = <spanclass="skimlinks-unlinked">thePreferences.edit</span>();
<spanclass="skimlinks-unlinked">edit.clear</span>();
edit.putInt(KEY_PREFERENCES_VERSION, currentVersion);
edit.commit();
}
}
}
SharedPreferences 数据存储在app文件夹下的xml文件下。
// yours preferences
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PREFS_NAME.xml // default preferences
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml
示例代码
publicclassPreferencesManager {
privatestaticfinalString PREF_NAME ="<span class="skimlinks-unlinked">com.example.app.PREF_NAME";
privatestaticfinalString KEY_VALUE ="<span class="skimlinks-unlinked">com.example.app.KEY_VALUE";
privatestaticPreferencesManager sInstance;
privatefinalSharedPreferences mPref;
privatePreferencesManager(Context context) {
mPref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
publicstaticsynchronizedvoidinitializeInstance(Context context) {
if(sInstance ==null) {
sInstance =newPreferencesManager(context);
}
}
publicstaticsynchronizedPreferencesManager getInstance() {
if(sInstance ==null) {
thrownewIllegalStateException(PreferencesManager.class.getSimpleName() +
" is not initialized, call initializeInstance(..) method first.");
}
returnsInstance;
}
publicvoidsetValue(longvalue) {
mPref.edit()
.putLong(KEY_VALUE, value)
.commit();
}
publiclonggetValue() {
returnmPref.getLong(KEY_VALUE,);
}
publicvoidremove(String key) {
mPref.edit()
.remove(key)
.commit();
}
publicbooleanclear() {
returnmPref.edit()
.clear()
.commit();
}
}
本文代码可以在github上找到。
Android SharedPreference最佳实践的更多相关文章
- Android开发最佳实践《IT蓝豹》
Android开发最佳实践 移动开发Android经验分享应用GoogleMaterial Design 摘要:前 段时间,Google公布了Android开发最佳实践的一系列课程,涉及到一些平时 ...
- Android开发最佳实践
Android开发最佳实践 摘要 ●使用 Gradle 和它推荐的工程结构 ●把密码和敏感数据放在gradle.properties ●不要自己写 HTTP 客户端,使用Volley或OkHttp库 ...
- [转]Android开发最佳实践
——欢迎转载,请注明出处 http://blog.csdn.net/asce1885 ,未经本人同意请勿用于商业用途,谢谢—— 原文链接:https://github.com/futurice/and ...
- Android 异常处理最佳实践
一个好的app 异常处理机制 我认为应该至少包含以下几个功能: 1.能把错误信息上传到服务器 让开发者可以持续改进app 2.错误信息至少应该包含 是否在主进程 是否在主线程 等可以帮助程序员定位的 ...
- 转:使用Android API最佳实践
原文来自于:http://blog.jobbole.com/65170/ 写在前面 现在,Android应用程序中集成第三方API已十分流行.应用程序都有自己的网络操作和缓存处理机制,但是大部分比较脆 ...
- Android 涂鸦最佳实践
Android中实现手势画图一般都两种方式,一是直接在View上绘制,而是使用SurfaceView. 两者还是有一些差别的.简介下. View:显示视图,内置画布,提供图形绘制函数.触屏事件.按键事 ...
- Android 开发最佳实践
原文地址:https://github.com/futurice/android-best-practices/blob/master/translations/Chinese/README.cn.m ...
- (转)iOS 最佳实践
本文转自http://www.jianshu.com/p/b0bf2368fb95 感谢作者和译者 iOS最佳实践 iOS最佳实践 译者注 本文翻译自 futurice 公司的 iOS Good Pr ...
- Android和PHP开发最佳实践
Android和PHP开发最佳实践 <Android和PHP开发最佳实践>基本信息作者: 黄隽实丛书名: 移动应用开发技术丛书出版社:机械工业出版社ISBN:9787111410508上架 ...
随机推荐
- leetcode Binary Tree Paths python
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = ...
- Java学习之finally关键字总结
Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使 ...
- 【phpcms-v9】如何实现在含有子栏目的栏目下添加内容?
对于题目的解释: 假设现在有一个一级栏目 为:栏目1 其下有二级栏目 :栏目1=>栏目11,栏目1=>栏目12,栏目1=>栏目13 同时栏目1下有文章列表 : 栏目1-----文章 ...
- ecside入门
ECSide是有一个基于jsp tag的开源列表组件. 简单的说,它就是一组可以帮助你快速实现强大的列表的jsp标签. 它的工作原理很简单. 您将要展现的列表的数据集合(Collection),放入r ...
- Java 拾遗
1.选择表达式中的类型转换 public class Test { public void static main(String args[]){ int i = 5; System.out.prin ...
- XP下Virtualbox虚拟Ubuntu共享文件夹设置
环境:主机操作系统是Windows XP,虚拟机是Ubuntu 8.10,虚拟机是VirtualBox 2.1.0. 1. 安装增强功能包(Guest Additions) 安装好Ubuntu 8.1 ...
- Office 2010简体中文正式版完美终身破解版免费下载
名称:Microsoft Office Professional 2010 正式版(JK破解免序列号安装版) Microsoft Office 2010 专业版 优点:用官方Microsoft off ...
- spring的作用及优势---第一个spring示例
Spring 的作用及优势 * Spring 用于整合,好处是解耦. 解耦,可以降低组件不组件乊间的关联,改善程序结构,便于系统的维护和扩展. 我们在使用 Spring 框架时,主要是使用 Spri ...
- 细说javascript函数
javascript函数是一个比较奇怪的东西,接触一段时间你就会犯迷糊,弄不明白它到底是什么了.你是否会因为有的javascript函数没有名字而莫名其妙,是否会因为javascript函数的参数没有 ...
- docker exec 运行命令
docker:/root/sbin# docker exec -it 17aaf60ee3a1 /sbin/ifconfig -a eth1 Link encap:Ethernet HWaddr 22 ...