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最佳实践的更多相关文章

  1. Android开发最佳实践《IT蓝豹》

    Android开发最佳实践   移动开发Android经验分享应用GoogleMaterial Design 摘要:前 段时间,Google公布了Android开发最佳实践的一系列课程,涉及到一些平时 ...

  2. Android开发最佳实践

    Android开发最佳实践 摘要 ●使用 Gradle 和它推荐的工程结构 ●把密码和敏感数据放在gradle.properties ●不要自己写 HTTP 客户端,使用Volley或OkHttp库 ...

  3. [转]Android开发最佳实践

    ——欢迎转载,请注明出处 http://blog.csdn.net/asce1885 ,未经本人同意请勿用于商业用途,谢谢—— 原文链接:https://github.com/futurice/and ...

  4. Android 异常处理最佳实践

    一个好的app 异常处理机制 我认为应该至少包含以下几个功能: 1.能把错误信息上传到服务器  让开发者可以持续改进app 2.错误信息至少应该包含 是否在主进程 是否在主线程 等可以帮助程序员定位的 ...

  5. 转:使用Android API最佳实践

    原文来自于:http://blog.jobbole.com/65170/ 写在前面 现在,Android应用程序中集成第三方API已十分流行.应用程序都有自己的网络操作和缓存处理机制,但是大部分比较脆 ...

  6. Android 涂鸦最佳实践

    Android中实现手势画图一般都两种方式,一是直接在View上绘制,而是使用SurfaceView. 两者还是有一些差别的.简介下. View:显示视图,内置画布,提供图形绘制函数.触屏事件.按键事 ...

  7. Android 开发最佳实践

    原文地址:https://github.com/futurice/android-best-practices/blob/master/translations/Chinese/README.cn.m ...

  8. (转)iOS 最佳实践

    本文转自http://www.jianshu.com/p/b0bf2368fb95 感谢作者和译者 iOS最佳实践 iOS最佳实践 译者注 本文翻译自 futurice 公司的 iOS Good Pr ...

  9. Android和PHP开发最佳实践

    Android和PHP开发最佳实践 <Android和PHP开发最佳实践>基本信息作者: 黄隽实丛书名: 移动应用开发技术丛书出版社:机械工业出版社ISBN:9787111410508上架 ...

随机推荐

  1. php mysql_insert_id() 获取为空

    mysql_insert_id() 获取插入数据后的最新的id 遇到问题和解决的步骤如下: 1. 使用后总是返回空的字符串,网上查了一番有人说是id要AUTO_INCREMENT,并且mysql_in ...

  2. 谁能告诉我为什么sum_area输出总是0(多边形重心问题)

    多边形重心问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 在某个多边形上,取n个点,这n个点顺序给出,按照给出顺序将相邻的点用直线连接, (第一个和最后一个连接 ...

  3. QF——iOS代理模式

    iOS的代理模式: A要完成某个功能,它可以自己完成,但有时出于一些原因,不方便自己完成.这时A可以委托B来帮其完成此功能,即由B代理完成.但是这个功能不是让B随随便便任其完成.此时,会有一个协议文件 ...

  4. jQuery 之 $.get、$.post、$.getJSON、$.ajax

    对 JSTL标签 加以巩固,同时在自己的博客中与之分享: http://app.yinxiang.com/shard/s20/sh/76feadb0-957a-40bc-895d-4d28025ce2 ...

  5. poj2190

    #include <stdio.h> #include <stdlib.h> int main() { ]; ,i; scanf("%s",arr); ;i ...

  6. HDOJ2031进制转换

    项目做久了,我发现自己对代码的实现能力越来越差劲了!经过前一段时间找工作的经历就能够明显感觉的到自己的代码熟练度不够!因此,今后要多加练习.要想做好一个优秀的程序猿就要多写程序,多思考. ★结题思路 ...

  7. 统计分析SQL Server Profiler 跟踪的SQL

    --跟踪文件读入到表中分析 SELECT * INTO ZGSJY FROM fn_trace_gettable('E:\wxxcdbprofiler.trc', default); --某时间内,最 ...

  8. md笔记——正则学习

    正则表达式 在线调试正则1 在线调试正则2 规则记录 \d 匹配一个数字字符.等价于[0-9] \D 匹配一个非数字字符.等价于[^0-9]. . 通配符,可以匹配任意字符. ? 表示量词" ...

  9. SQL Server 使用ROW_NUMBER()进行分页

    代码示例: WITH domain AS(SELECT ROW_NUMBER() OVER(ORDER BY ID DESC) ids,* FROM dbo.DomainInfo) SELECT * ...

  10. 【转】引入android项目在eclipse ADT中显示中文乱码问题

    (1)修改工作空间的编码方式:Window->Preferences->General->Workspace->Text file Encoding在Others里选择需要的编 ...