1. 定义
SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。(简称SP)
2. 作用
SP用xml文件存放数据,文件存放在/data/data/<package name>/shared_prefs目录下。
3. 代码
(1)添加参数
SharedPreferences sharedPreferences = getSharedPreferences("wenjianming", Context.MODE_PRIVATE); //创建SP对象,指定文件名为wenjianming和指定读写模式为私有模式
Editor editor = sharedPreferences.edit();//获取编辑器,用于添加参数
editor.putString("param1", "111111");//添加String参数
editor.putInt("param2", 22222);//添加Int参数
editor.commit();//最后,提交修改
(2)读取参数
SharedPreferences sharedPreferences = getSharedPreferences("wenjianming", Context.MODE_PRIVATE);//创建SP对象,指定文件名为wenjianming和指定读写模式为私有模式
sharedPreferences.getString("param1", "");//获取String参数
sharedPreferences.getInt("param2", 0);//获取Int参数
4. XML存储格式
(1)文件格式
wenjianming.xml
(2)文件内容
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="param1">111111</string>
<int name="param2" value="2222" />
</map>
5. 文件读写模式
1. MODE_APPEND: 追加方式存储
解:这个模式我觉得可以直接忽视了。首先,文件的追加模式存储,一般是直接从内容的末尾开始存储,但是事实并不一定是从末尾追加。其次,官方的解释是“这个模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件”,这句话是句废话,当文件不存在的情况下,MODE_PRIVATE模式也会创建文件。
2. MODE_PRIVATE: 私有方式存储,其他应用无法访问(默认方式)
解:这是通常建议使用的模式。
3. MODE_WORLD_READABLE: 表示当前文件可以被其他应用读取
解:不是一个安全的模式,不建议使用。再说,跨进程通信也不会使用SP。
4. MODE_WORLD_WRITEABLE: 表示当前文件可以被其他应用写入
解:不是一个安全的模式,不建议使用。再说,跨进程通信也不会使用SP。
6. 文件生成的时机
SP有两个方法可以提交数据:
editor.commit();//效率低,线程安全
editor.apply();//效率高,线程不安全
以上两个方法执行时,如果没有文件,则创建文件。
区别:
- apply没有返回值而commit返回boolean表明修改是否提交成功
- apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘, 而commit是同步的提交到硬件磁盘,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。而apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率。
- apply方法不会提示任何失败的提示。
由于在一个进程中,sharedPreference是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,建议使用apply,当然需要确保提交成功且有后续操作的话,还是需要用commit的。
7. 获取SP对象的三种方法
(1)基于Context,需指定文件名和读写模式
SharedPreferences sharedPreferences = getSharedPreferences("wenjianming", Context.MODE_PRIVATE);//创建SP对象,指定文件名为wenjianming和指定读写模式为私有模式
(2)基于Context,获取默认SP
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
默认SP的文件名和读写模式可以从源码中可以看出
public static String getDefaultSharedPreferencesName(Context context) {
return context.getPackageName() + "_preferences";
}
private static int getDefaultSharedPreferencesMode() {
return Context.MODE_PRIVATE;
}
(3)基于Activity获取SP对象,只需要指定模式
SharedPreferences sharedPreferences = getPreferences(Context.MODE_PRIVATE);
文件的命名方式可以从源码中可以看出
@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);
}
8. 养成良好的封装习惯
import android.content.Context;
import android.content.SharedPreferences;
public class SharePreferencesUtils {
private SharedPreferences sharedPreferences;
/**
* 构造方法
* @param context
* @param fileName
*/
public SharePreferencesUtils(Context context, String fileName) {
sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
}
/**
* 创建一个内部类使用,里面有key和value这两个值
*/
public static class ContentValue {
String key;
Object value;
public ContentValue(String key, Object value) {
this.key = key;
this.value = value;
}
}
/**
* 传值
* @param contentValues
*/
public void putValues(ContentValue... contentValues) {
SharedPreferences.Editor editor = sharedPreferences.edit();
for (ContentValue contentValue : contentValues) {
//如果是字符型类型
if (contentValue.value instanceof String) {
editor.putString(contentValue.key, contentValue.value.toString()).commit();
}
//如果是int类型
if (contentValue.value instanceof Integer) {
editor.putInt(contentValue.key, Integer.parseInt(contentValue.value.toString())).commit();
}
//如果是Long类型
if (contentValue.value instanceof Long) {
editor.putLong(contentValue.key, Long.parseLong(contentValue.value.toString())).commit();
}
//如果是布尔类型
if (contentValue.value instanceof Boolean) {
editor.putBoolean(contentValue.key, Boolean.parseBoolean(contentValue.value.toString())).commit();
}
}
}
public String getString(String key) {
return sharedPreferences.getString(key, null);
}
public boolean getBoolean(String key) {
return sharedPreferences.getBoolean(key, false);
}
public int getInt(String key) {
return sharedPreferences.getInt(key, -1);
}
public long getLong(String key) {
return sharedPreferences.getLong(key, -1);
}
//清除当前文件的所有的数据
public void clear() {
sharedPreferences.edit().clear().commit();
}
}
怎么使用这个工具类不需要多说了。
特别注意:
SP是一个轻量级的存储类,因为考虑到内存问题,key和value字符不能太长,字符越长,文件占用的存储空间越大,读取配置文件的时间太长,占用的内存过大,导致手机卡顿。
网友评论