概述
SharedPreferences是Android平台中一个轻量级存储方案,用来保存应用程序中一些常用的配置参数,主要保存的是一些boolean,int,float,long,String等类型数据。使用SharedPreferences保存数据,本质是基于XML文件以key-value键值对方式存储数据,存放文件的路径为:/data/data//shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过SharedPreferences.Editor对象实现。
应用实例
将数据保存至SharedPreferences
SharedPreferences sharedPreferences = getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor= sharedPreferences.edit();
editor.putString("111", "aaa");
editor.commit();
获取SharedPreferences中的数据
SharedPreferences sharedPreferences = getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
String str = sharedPreferences.getString("111", "");
关于SharedPreferences四种操作模式:
Context.MODE_PRIVATE :默认的操作模式,只能被应用程序本身访问。亦可用0表示;
Context.MODE_WORLD_READABLE :在API 17 中过期,不建议使用;
Context.MODE_WORLD_WRITEABLE :在API 17 中过期,不建议使用;
Context.MODE_MULTI_PROCESS:在进行操作文件时,会进行多线程检查;
注意:
目前网上很多关于SharedPreferences模式说明,其中有不少错误的说法,比如Context.MODE_APPEND也属于该类的操作模式,并指出该模式是用来追加文件内容,而Context.MODE_PRIVATE则是写入的内容会覆盖之前的原文件的内容。我通过自身实验和查看API得出,发现Context.MODE_APPEND并不用在getSharedPreferences中,而是用在openFileOutput中,并且SharedPreferences中使用Context.MODE_PRIVATE时,并不会覆盖之前原文件的内容,而是采用追加的模式。希望大家能够特别注意。
获取SharedPreferences的三种方式
1:调用Context对象的getSharedPreferences方式;
2:调用Activity对象的getPreferences方式;
3:调用PreferenceManager对象的getDefaultSharedPreferences方式;
三种方式的区别:
1。使用getSharedPreferences(String name, int mode)时,可以自定义生成的XML文件的名字。
2。使用getPreferences(int mode)时,生成的是以该Activity命名的XML文件。
查看源代码中:
/**
* Retrieve a {@link SharedPreferences} object for accessing preferences
* that are private to this activity. This simply calls the underlying
* {@link #getSharedPreferences(String, int)} method by passing in this activity's
* class name as the preferences name.
*
* @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default
* operation, {@link #MODE_WORLD_READABLE} and
* {@link #MODE_WORLD_WRITEABLE} to control permissions.
*
* @return Returns the single SharedPreferences instance that can be used
* to retrieve and modify the preference values.
*/
public SharedPreferences getPreferences(int mode) {
return getSharedPreferences(getLocalClassName(), mode);
}
/**
* Returns class name for this activity with the package prefix removed.
* This is the default name used to read and write settings.
*
* @return The local class name.
*/
@NonNull
public String getLocalClassName() {
final String pkg = getPackageName();
final String cls = mComponent.getClassName();
int packageLen = pkg.length();
if (!cls.startsWith(pkg) || cls.length() <= packageLen
|| cls.charAt(packageLen) != '.') {
return cls;
}
return cls.substring(packageLen+1);
}
————ContextWrapper类————————-
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return mBase.getSharedPreferences(name, mode);
}
从上面我们可以看到,在执行Activity.getPreferences后,在方法内部执行的还是getSharedPreferences方法,这里与第一种方式一致,只不过里面传入的参数是通过getLocalClassName方法获得当前类的名字,所以生成XML文件的名称为当前Activity的类名。
3。使用getDefaultSharedPreferences(Context context)时,生成的是以_preferences命名的文件。
查看源代码中:
/** * Gets a SharedPreferences instance that points to the default file that is * used by the preference framework in the given context. * * @param context The context of the preferences whose values are wanted. * @return A SharedPreferences instance that can be used to retrieve and * listen to values of the preferences. */
public static SharedPreferences getDefaultSharedPreferences(Context context) {
return context.getSharedPreferences(getDefaultSharedPreferencesName(context),
getDefaultSharedPreferencesMode());
}
private static String getDefaultSharedPreferencesName(Context context) {
return context.getPackageName() + "_preferences";
}
private static int getDefaultSharedPreferencesMode() {
return Context.MODE_PRIVATE;
}
————ContextWrapper类————————-
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return mBase.getSharedPreferences(name, mode);
}
从上面可以看出执行PreferenceManager.getDefaultSharedPreferences方法时,在getDefaultSharedPreferences内部,首先获得要生成的文件的名字,这里采用包名+”_preferences”的方式,然后设置默认的模式,最后还是调用getSharedPreferences方法,与上面两种方式相同。
总结:虽然上面三种获得SharedPreferences的方式不相同,但是最后都是通过context.getSharedPreferences来得到存储的文件。它们的区别在于执行后,生成不同的文件名的文件,所以在开发过程中,可以选择自身偏好的方式。
编写工具类
import java.util.HashSet;
import java.util.Set;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.TextUtils;
/** * 工具类:SharedPreferences 存储和读取String,int,boolean,StringSet等数据 * * 注意:使用该类之前必须先初始化,调用getInstance()方法,否则会报错。 * * @author yuminfeng 2016-05-12 * */
public class SharedPrefsUtil {
private static Context context;
private static SharedPrefsUtil util;
private SharedPrefsUtil(Context context) {
this.context = context;
}
public static SharedPrefsUtil getInstance(Context context) {
if (util == null) {
synchronized (SharedPrefsUtil.class) {
if (util == null) {
util = new SharedPrefsUtil(context.getApplicationContext());
}
}
}
return util;
}
/** * 生成的xml文件名称为:<package_name>_preferences.xml * * @return */
private static SharedPreferences getPreferences() {
if (null == context) {
return null;
}
return PreferenceManager.getDefaultSharedPreferences(context);
}
public static String getString(String key) {
if (TextUtils.isEmpty(key)) {
return "";
}
return getString(key, "");
}
public static String getString(String key, String defValue) {
if (TextUtils.isEmpty(key)) {
return "";
}
SharedPreferences sp = getPreferences();
return sp.getString(key, defValue);
}
public static void setString(String key, String value) {
if (TextUtils.isEmpty(key)) {
return;
}
SharedPreferences.Editor editor = getPreferences().edit();
editor.putString(key, value);
editor.commit();
}
public static int getInt(String key) {
if (TextUtils.isEmpty(key)) {
return -1;
}
return getInt(key, -1);
}
public static int getInt(String key, int defValue) {
if (TextUtils.isEmpty(key)) {
return -1;
}
SharedPreferences sp = getPreferences();
return sp.getInt(key, defValue);
}
public static void setInt(String key, int value) {
if (TextUtils.isEmpty(key)) {
return;
}
SharedPreferences.Editor editor = getPreferences().edit();
editor.putInt(key, value);
editor.commit();
}
public static boolean getBoolean(String key) {
if (TextUtils.isEmpty(key)) {
return false;
}
return getBoolean(key, false);
}
public static boolean getBoolean(String key, boolean defValue) {
if (TextUtils.isEmpty(key)) {
return false;
}
SharedPreferences sp = getPreferences();
return sp.getBoolean(key, defValue);
}
public static void setBoolean(String key, boolean value) {
if (TextUtils.isEmpty(key)) {
return;
}
SharedPreferences.Editor editor = getPreferences().edit();
editor.putBoolean(key, value);
editor.commit();
}
public static Set<String> getStringSet(String key, Set<String> defValue) {
if (TextUtils.isEmpty(key)) {
HashSet<String> set = new HashSet<String>();
set.clear();
return set;
}
SharedPreferences sp = getPreferences();
return sp.getStringSet(key, defValue);
}
public static void setStringSet(String key, Set<String> value) {
if (TextUtils.isEmpty(key)) {
return;
}
SharedPreferences.Editor editor = getPreferences().edit();
editor.putStringSet(key, value);
editor.commit();
}
}