SharedPreferences - Android Key-Value键值存储

写SudaLogin Android app时,使用了SharedPreferences来实现保存配置信息等Key-Value形式的数据。

SharedPreferences - Android Key-Value键值存储

1 SharedPreferences

  • SharedPreferences 适用于存储小型数据,如配置信息,设置项。

1.1 依赖包

1
2
import android.content.Context;
import android.content.SharedPreferences;

1.2 读取示例

1
2
3
4
5
6
7
8
// 获得SharedPreferences对象
SharedPreferences preferences = MainActivity.this.getSharedPreferences("SudaLoginDev", Context.MODE_PRIVATE);

// SharedPreferences支持Java的基本数据类型
// 参数1为key,参数2为默认返回的value(如找不到存储的键值)
preferences.getInt("frequency", 0);
prefenences.getString("username", "");
preferences.getBoolean("enable", true);

1.3 写入示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 获得SharedPreferences对象
SharedPreferences preferences = MainActivity.this.getSharedPreferences("SudaLoginDev", Context.MODE_PRIVATE);
// 获得编辑器对象
SharedPreferences.Editor editor = preferences.edit();

// SharedPreferences支持Java的基本数据类型
// 参数1为key,参数2为对应的value
editor.putInt("frequency", 1);
editor.putString("username", "name1");
editor.putBoolean("enable", true);

// 写入编辑结束后,须提交
// editor.commit();
editor.apply(); // 优化:apply自动优化写入时机,性能比占用同步资源的commit更好
  • 我编写的时候,发现网上的资料大多老旧,还在使用editor.commit()。Android官方现推荐调用editor.apply(),以求达到更好的 IO 性能。
  • 欣赏下Android的文档 - commit()apply()方法的Declaration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Commit your preferences changes back from this Editor to the
* {@link SharedPreferences} object it is editing. This atomically
* performs the requested modifications, replacing whatever is currently
* in the SharedPreferences.
*
* <p>Note that when two editors are modifying preferences at the same
* time, the last one to call commit wins.
*
* <p>If you don\'t care about the return value and you\'re
* using this from your application\'s main thread, consider
* using {@link #apply} instead.
*
* @return Returns true if the new values were successfully written
* to persistent storage.
*/
boolean commit();
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
28
29
30
31
32
33
34
35
36
37
/**
* Commit your preferences changes back from this Editor to the
* {@link SharedPreferences} object it is editing. This atomically
* performs the requested modifications, replacing whatever is currently
* in the SharedPreferences.
*
* <p>Note that when two editors are modifying preferences at the same
* time, the last one to call apply wins.
*
* <p>Unlike {@link #commit}, which writes its preferences out
* to persistent storage synchronously, {@link #apply}
* commits its changes to the in-memory
* {@link SharedPreferences} immediately but starts an
* asynchronous commit to disk and you won\'t be notified of
* any failures. If another editor on this
* {@link SharedPreferences} does a regular {@link #commit}
* while a {@link #apply} is still outstanding, the
* {@link #commit} will block until all async commits are
* completed as well as the commit itself.
*
* <p>As {@link SharedPreferences} instances are singletons within
* a process, it\'s safe to replace any instance of {@link #commit} with
* {@link #apply} if you were already ignoring the return value.
*
* <p>You don\'t need to worry about Android component
* lifecycles and their interaction with <code>apply()</code>
* writing to disk. The framework makes sure in-flight disk
* writes from <code>apply()</code> complete before switching
* states.
*
* <p class=\'note\'>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 <code>apply()</code>, you can simply call
* {@link #commit} from <code>apply()</code>.
*/
void apply();
  • 阅读即知,apply()是异步(asynchronous)写入,会根据修改情况,自动优化写入时机,以减少IO访问次数,实现更好的IO性能。而commit()则是同步写入(synchronous),特别是应用主线程中,为减少同步等待,使用apply()方法更好。

1.4 其它

另外还有如editor.remove()editor.clear()等API,具体使用时查看Declaration即可。Android的Declaration部分代码及注释编写非常详实规范,在此赞叹一番。