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上架 ...
随机推荐
- EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数
记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...
- MFC CListCtrl得到ctrl,shift多选的行号
vector<int> selVect; int count = m_consumeList.GetItemCount(); //你的列表多少行 for (int i = 0; i< ...
- 关于html标签元素的data-*属性
关于这个主题的文章和博客其实已经非常多了,这里并非要重复造轮子,只是看到一些例子稍微有点麻烦,其实也很简单,但是对于一个刚刚入门的人,w3c的例子甚至可能看不懂,这里列出一个最简单不过的小案例以供参考 ...
- FLAG_ACTIVITY_NEW_TASK和SingleInstance的设计思路(多task的应用)
这部分的想法都是基于以下两点: 1.Activity可能被复用,可能是复用Activity的功能,还可能是复用Activity的状态: 2.Task的作用:target,同一个task中的Activi ...
- 3D模型选中显示样式改变
osg::ref_ptr<osg::Material> material = new osg::Material(); //模型材质信息 material->setTranspare ...
- 《转》Java 信号量 Semaphore 介绍
该文章转自:http://www.cnblogs.com/whgw/archive/2011/09/29/2195555.html Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个 ...
- TFS Build Definition
1. TFS Build 简介 在团队项目开发中,编译常常是一个很困难的事情! 可能你会反问编译有什么难的?不就是右键,然后点击 Build/Rebuild, 或者直接按 F5 么?这都不会,真不知 ...
- 如何在 静态编译的QT 5.5.1 中 使用数据库插件连接 ODBC(调用静态插件)
前段时间由于工作的关系,需要编写一个将数据插入到 Sql server 2012 的桌面软件. 由于之前使用的是MFC,偶然间接触到了Qt后,被它的简洁惊艳到了,于是便毅然而然的转投到了Qt的怀抱,哈 ...
- poj2262---素数(质数)的判断
收获:一开始以为是100万的所有数字,题目要求是只要偶数,也可以分析出来,如果是给一个奇数,当我们给他大于等于3的奇数(这个数加有可能不是质数,但至少满足是奇数,至于是不是质数还要自己判断),剪出来一 ...
- oracle初始安装大小
oracle初始安装大小 /ruiy/ocr/DBSoftware/app/oracle/ruiy/ocr/DBSoftware/app/oraInventory/ruiy/ocr/DBData/or ...