根据Context获取SharedPreferences对象
利用edit()方法获取Editor对象。
通过Editor对象存储key-value键值对数据。
通过apply()或者commit()方法提交数据。
SharedPreferences.Editor api:完成数据写入操作
commit()方法与apply()方法的比较
二者都是提交preference修改数据
二者都是原子过程。
apply没有返回值而commit返回boolean表明修改是否提交成功
apply是将修改数据原子提交到内存,而后异步真正提交到硬件磁盘;而commit是同步的提交到硬件磁盘,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。而apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率。
apply方法不会提示任何失败的提示。
对api的理解
1. commit介绍:public abstract boolean commit ()
修改你的preferences,从Editor到SharePreferences。它执行所请求的修改,替代SharedPreferences中的任何数据,当2个editor同时修改preferences ,最后一个commit成功。如果不关注返回值或在程序的main线程使用时,推荐使用apply().
2. apply介绍:public abstract void apply ()
区别:commit将同步的将数据写到preferences;apply立即更改内存中的SharedPreferences,但是开始异步提交到磁盘中。保存失败你也不会得到任何提示信息,如果在这个sharedPreferences有另外一个editor执行一个定期的commit,此时一个apply依旧未完成。commit将被阻塞,直到所有异步操作完成,以及自己的commit。由于SharedPreferences在进程中是单实例的。在忽悠返回值的前提下,取代任何实例的commit或apply都是安全的。
commit()方法与apply()方法原文解释
Commit your preferences changes back from this Editor to the SharedPreferences
object it is editing. This atomically performs the requested modifications, replacing whatever is currently in the SharedPreferences.
Note that when two editors are modifying preferences at the same time, the last one to call apply wins.
Unlike commit()
, which writes its preferences out to persistent storage synchronously, apply()
commits its changes to the in-memory SharedPreferences
immediately but starts an asynchronous commit to disk and you won't be notified of any failures. If another editor on this SharedPreferences
does a regular commit()
while a apply()
is still outstanding, the commit()
will block until all async commits are completed as well as the commit itself.
As SharedPreferences
instances are singletons within a process, it's safe to replace any instance of commit()
with apply()
if you were already ignoring the return value.
You don't need to worry about Android component lifecycles and their interaction with apply()
writing to disk. The framework makes sure in-flight disk writes from apply()
complete before switching states.
The SharedPreferences.Editor interface isn't expected to be implemented directly. However, if you previously did implement it and are now getting errors about missing apply()
, you can simply call commit()
fromapply()
.
Commit your preferences changes back from this Editor to the SharedPreferences
object it is editing. This atomically performs the requested modifications, replacing whatever is currently in the SharedPreferences.
Note that when two editors are modifying preferences at the same time, the last one to call commit wins.
If you don't care about the return value and you're using this from your application's main thread, consider using apply()
instead.
Returns true if the new values were successfully written to persistent storage.
如果你希望传入的Set是一个有序的(跟插入时的顺序一样),那么使用LinkedHashSet<String>类型,构造好一个LinkedHashSet<String>对象之后,
调用 SharedPreferences.Editor的putStringSet(String key, Set<String> values)写入。 按照常规的思维,通过SharedPreferences的getStringSet(String key)方法读取出来数据,
然后强制转为LinkedHashLinked<String>,可是出现异常了,系统提示不能将HashSet<String>转为LinkedHashSet<String>类型。也就是说取出来的值已经不再是我们写入的类型了。
所以就只能使用HashSet<String>默认的排序类型,这只能满足那些不关系顺序的情况。
四、SharedPreferences一次存入多个有序数据解决方案 (String 类型为例)——使用字符串拼接(StringBuilder)的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public
void
testSharedPreferences(Context context) {
// 写数据操作
final
String regularExpression =
"#"
;
final
String key =
"key"
;
final
String[] strings = {
"1111"
,
"2222"
,
"3333"
};
final
String defaultValue =
"5555"
;
final
String fileName =
"filename"
;
final
StringBuilder stringBuilder =
new
StringBuilder();
for
(
int
i =
0
; i < strings.length; i++) {
stringBuilder.append(strings[i]);
if
(i != strings.length -
1
) {
stringBuilder.append(regularExpression);
}
}
SharedPreferences preferencesWrite = context.getSharedPreferences(fileName, Context.MODE_WORLD_READABLE);
SharedPreferences.Editor editor = preferencesWrite.edit();
editor.putString(key, stringBuilder.toString());
editor.apply();
// 读数据操作
SharedPreferences preferencesRead = context.getSharedPreferences(fileName, Context.MODE_WORLD_READABLE);
final
String resultStr = preferencesRead.getString(key, defaultValue);
// 没有对应的key则返回“5555”
final
String[] resultArray = resultStr.split(regularExpression);
for
(String str : resultArray) {
System.out.println(str);
}
}
|
五、SharedPreferences多进程支持
1
2
3
4
5
6
7
8
9
|
public
static
int
getMode() {
// MODE_MULTI_PROCESS is always on in apps targeting Gingerbread
// (Android 2.3) and below, and off by default in later versions
return
Build.VERSION.SDK_INT >
8
?
4
:
0
;
}
public
void
test() {
SharedPreferences settings = context.getSharedPreferences(
"fileName"
, getMode());
}
|
下面是getSharedPreferences方法的定义和解释:
Retrieve and hold the contents of the preferences file 'name', returning a SharedPreferences through which you can retrieve and modify its values. Only one instance of the SharedPreferences object is returned to any callers for the same name, meaning they will see each other's edits as soon as they are made.
name | Desired preferences file. If a preferences file by this name does not exist, it will be created when you retrieve an editor (SharedPreferences.edit()) and then commit changes (Editor.commit()). |
---|---|
mode | Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions. The bit MODE_MULTI_PROCESS can also be used if multiple processes are mutating the same SharedPreferences file. MODE_MULTI_PROCESS is always on in apps targeting Gingerbread (Android 2.3) and below, and off by default in later versions. |
The single SharedPreferences
instance that can be used to retrieve and modify the preference values.
MODE_PRIVATE
MODE_WORLD_READABLE
MODE_WORLD_WRITEABLE
MODE_MULTI_PROCESS
SharedPreference loading flag: when set, the file on disk will be checked for modification even if the shared preferences instance is already loaded in this process. This behavior is sometimes desired in cases where the application has multiple processes, all writing to the same SharedPreferences file. Generally there are better forms of communication between processes, though.
This was the legacy (but undocumented) behavior in and before Gingerbread (Android 2.3) and this flag is implied when targetting such releases. For applications targetting SDK versions greater than Android 2.3, this flag must be explicitly set if desired.
getSharedPreferences(String, int)
File creation mode: the default mode, where the created file can only be accessed by the calling application (or all applications sharing the same user ID).
MODE_WORLD_READABLE
MODE_WORLD_WRITEABLE
This constant was deprecated in API level 17.
Creating world-readable files is very dangerous, and likely to cause security holes in applications. It is strongly discouraged; instead, applications should use more formal mechanism for interactions such asContentProvider
, BroadcastReceiver
, and Service
. There are no guarantees that this access mode will remain on a file, such as when it goes through a backup and restore. File creation mode: allow all other applications to have read access to the created file.
MODE_PRIVATE
MODE_WORLD_WRITEABLE
This constant was deprecated in API level 17.
Creating world-writable files is very dangerous, and likely to cause security holes in applications. It is strongly discouraged; instead, applications should use more formal mechanism for interactions such asContentProvider
, BroadcastReceiver
, and Service
. There are no guarantees that this access mode will remain on a file, such as when it goes through a backup and restore. File creation mode: allow all other applications to have write access to the created file.
MODE_PRIVATE
MODE_WORLD_READABLE