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上架 ...
随机推荐
- 编程实现任意长度整数的加法(整数可以长度超出C++中int范围)
#include <iostream> #include<string> using namespace std; string add(string s1,string s2 ...
- linux杂记(三)linux指令介绍
[root@linux ~]# command [-options] parameter1 parameter2 说明: 最左边的root显示的是[目前使用者的账号],而@之后接的是linux即[主机 ...
- codeforces 653D. Delivery Bears 网络流
题目链接 我们二分每个人携带的数量, 然后每个边的容量就相当于min(权值/二分的值, x). x是人的数量. 然后判断是否满流就可以. 这么裸的网络流为竟然没看出来. 注意写fsbs(r-l)> ...
- MySQL二进制日志中保存的上下文信息
1.二进制日志中要保存上下文的原因 二进制日志是要在slave端重放的,记录上下文信息,是为了保证主丛数据库的一致.如rand一个随机数,在主上返回的可以有是100,在从上返回的可能就是1000了. ...
- eclipse中使用EasyExplorer插件定位文件 [转载]
如果你经常需要在Eclipse里打开相关资源文件所在的文件夹,比较麻烦,要右键,属性,在Location一栏中把所在的文件夹拷贝一下,然后再去资源管理器里输入这个路径,回车,打开它. 解决方法: 用E ...
- Office 2010 Toolkit and EZ-Activator
“Office 2010 Toolkit 2.0.1”是“迷你KMS”的更新换代版本.虽然是单一可执行程序,但一身承担两大职能:“KMS服务器”和“客户激活端”.“Office 2010 Toolki ...
- 减小Delphi的Exe文件大小(11种方法)
一般来说,由Delphi生成的EXE文件,要比其由它编程语言生成的体积大一些.这主要是由于使用VCL的原因(当然,VCL是有许多优点的!) 以下是减小EXE文件大小的几种途径: 01) 使用加壳工具( ...
- AndroidAutoLayout 屏幕适配
https://github.com/hongyangAndroid/AndroidAutoLayout
- CouldnotcreateServerSocketonaddress0.0.0.0/0.0.0.0:9083
错误记录 安装的时候遇到了如下错误 Exception in thread "main" org.apache.thrift.transport.TTransportExcepti ...
- iOS开发基本须要
iOS开发基本须要 1 准备好对应的硬件和软件配置------基于Intel处理器的Mac操作系统 2 具有C++,Java或其它面向对象编程语言的开发经验 3 最新的iphone SDK的下 ...