SharedPreferences:
是以键值对的方式存储数据,存储的位置是:/data/data/包名/shared_prefs目录下生成对应的sp.xml文件
优点 | 缺点 |
---|---|
操作简单,方便; 不需要创建数据库,数据表这样的操作; |
存储职能单一; 存储的数据类型有Boolean,int,float,long和String这五种简单的数据类型; 比起数据库无法进行条件查询 |
SharedPreferences有四种操作模式:
模式 | 描述 |
---|---|
Context.MODE_PRIVATE | 为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。 |
Context.MODE_APPEND | 模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。 |
MODE_WORLD_READABLE | 表示当前文件可以被其他应用读取。Android 4.2之后已经放弃使用了 |
MODE_WORLD_WRITEABLE | 表示当前文件可以被其他应用写入。Android 4.2之后已经放弃使用了 |
获取SharedPreference的两种方式:
编号 | 名称 | 描述 |
---|---|---|
1 | 调用Context对象的getSharedPreferences()方法 | 1.调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享. 2.文件名称不存在就会创建一个. |
2 | 调用Activity对象的getPreferences()方法 | 1.调用Activity对象的getPreferences()方法获得的SharedPreferences对象只能在该Activity中使用. 2.使用这个方法会自动将当前活动的类名作为SharedPreferences的文件名. |
3 | PreferenceManager获取SharedPreferences | 1.PreferenceManager.getDefaultSharedPreferences(Context) 2.使用这个方法会自动使用当前程序的包名作为前缀来命名SharedPreferences文件 |
SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的步骤如下:
一、获取SharedPreferences对象
二、利用edit()方法获取Editor对象。
三、通过Editor对象存储key-value键值对数据。
四、通过commit()方法提交数据。
Editor提供了两个提交的修改的方法:apply和commit,
相同点:
1.二者都是提交preference修改数据
2.二者都是原子过程。
区别:
名称 | 区别 |
---|---|
apply | 1.无返回值 2.apply是将修改数据原子提交到内存,而后异步真正提交到硬件磁盘,apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率。 |
commit | 1.返回boolean表明修改是否提交成功 2.commit是同步的提交到硬件磁盘,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。 |
综合上述,由于在一个进程中,sharedPreference是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,建议使用apply,当然需要确保提交成功且有后续操作的话,还是需要用commit的。
commit介绍:public abstract boolean commit ()
修改你的preferences,从Editor到SharePreferences。它执行所请求的修改,替代SharedPreferences中的任何数据.
当2个editor同时修改preferences ,最后一个commit成功。
如果不关注返回值或在程序的main线程使用时,推荐使用apply().
apply介绍:public abstract void apply ()
区别:
commit将同步的将数据写到preferences;apply立即更改内存中的SharedPreferences,但是开始异步提交到磁盘中。保存失败你也不会得到任何提示信息,
如果在这个sharedPreferences有另外一个editor执行一个定期的commit,此时一个apply依旧未完成。commit将被阻塞,直到所有异步操作完成,以及自己的commit。
由于SharedPreferences在进程中是单实例的。在忽略返回值的前提下,取代任何实例的commit或apply都是安全的。
实战:
public void SPSaveData(Map<String, String> map) {
WeakReference<Context> wrfContext = new WeakReference<Context>(this);
WeakReference<Map<String, String>> wrfMap = new WeakReference<Map<String, String>>(map);
if (null != wrfContext.get() && null != wrfMap.get()) {
SharedPreferences sp = wrfContext.get().getSharedPreferences(SP_FILENAME, MODE_PRIVATE);
//存入数据
SharedPreferences.Editor editor = sp.edit();
for (String key : wrfMap.get().keySet()) {
String enCodeKey = KYEncryption.INSTANCE.Base64Encode(key);
String enCodeValue = KYEncryption.INSTANCE.Base64Encode(wrfMap.get().get(key));
editor.putString(enCodeKey, enCodeValue);
}
editor.commit();
}
}
获取数据:
public String SPGetData(String key) {
WeakReference<Context> wrfContext = new WeakReference<Context>(this);
if (null != wrfContext.get()) {
SharedPreferences sp = wrfContext.get().getSharedPreferences(SP_FILENAME, MODE_PRIVATE);
String enCodekey = KYEncryption.INSTANCE.Base64Encode(key).trim();
String temp = null;
for (String s : sp.getAll().keySet()) {
if (enCodekey.equals(s.trim())) {
temp = sp.getAll().get(s).toString();
break;
}
}
if (null != temp) {
return new String(KYDecryption.INSTANCE.Base64Decode(temp));
}
}
return null;
}