简介

一个轻量级的存储类,以键值对的 XML 文件形式将数据存储在本地,程序卸载后也会一并清除,不会残留信息。

要想使用 SharedPreferences 来存储数据,首先需要获取到 SharedPreferences 对象。 Android 中主要提供了 3 种方法用于得到 SharedPreferences 对象。

  1. Context 类中的 getSharedPreferences() 方法
    此方法接收两个参数,第一个参数用于指定 SharedPreferences 文件的名称,如果指定的文件不存在则会创建一个, SharedPreferences 文件都是存放在 /data/data/<packagename>/shared_prefs/ 目录下的。第二个参数用于指定操作模式,目前只有 MODE_PRIVATE 这一种模式可选,它是默认的操作模式,和直接传入 0 效果是相同的,表示只有当前的应用程序才可以对这个 SharedPreferences 文件进行读写。
    其他几种操作模式均已被废弃, MODE_WORLD_READABLEMODE_WORLD_WRITEABLE 这两种模式是在 Android 4.2 版本中被废弃的, MODE_MULTI_PROCESS 模式是在 Android 6.0 版本中被废弃的。

Context.MODE_PRIVATE : 指定该 SharedPreferences 数据只能被本应用程序读、写;
Context.MODE_WORLD_READABLE : 指定该 SharedPreferences 数据能被其他应用程序读,但不能写;
Context.MODE_WORLD_WRITEABLE : 指定该 SharedPreferences 数据能被其他应用程序读;
Context.MODE_APPEND :该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件;

  1. Activity 类中的 getPreferences() 方法
    这个方法和 Context 中的 getSharedPreferences() 方法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为 SharedPreferences 的文件名。
  2. PreferenceManager 类中的 getDefaultSharedPreferences() 方法
    这是一个静态方法,它接收一个 Context 参数,并自动使用当前应用程序的包名作为前缀来命名 SharedPreferences 文件。


使用

SharedPreferences 对象本身只能获取数据而不支持存储和修改,存储修改是通过 SharedPreferences.edit() 获取的内部类 Editor 对象实现。

// 写入数据
SharedPreferences sharedPreferences = getSharedPreferences("data", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("name", "Tom");
editor.putInt("age", 28);
editor.putBoolean("married", false);
editor.apply();

// 读取数据
SharedPreferences sharedPreferences = getSharedPreferences("data", Context.MODE_PRIVATE);
String userId = sharedPreferences.getString("name", "");

// 删除指定数据
editor.remove("name");
editor.commit();

// 清空数据
editor.clear();
editor.commit();



优点

  1. 轻量级,以键值对的方式进行存储,使用方便,易于理解。
  2. 采用的是 XML 文件形式存储在本地,程序卸载后会也会一并被清除,不会残留信息。


缺点

  1. 由于是对文件 IO 读取,因此在 IO 上的瓶颈是个大问题。
  2. 多线程场景下效率比较低,因为 get 操作的时候,会锁定 SharedPreferencesImpl 里面的对象,互斥其他操作,而当 putcommit()apply() 操作的时候都会锁住 Editor 的对象,这样的情况下,效率会降低。
  3. 不支持跨进程通讯。
  4. 由于每次都会把整个文件加载到内存中,因此,如果 SharedPreferences 文件过大,或者在其中的键值对是大对象的 json 数据则会占用大量内存,读取较慢是一方面,同时也会引发程序频繁GC,导致的界面卡顿。


使用建议

  1. 不要存储较大数据或者较多数据到 SharedPreferences 中。
  2. 键值对不宜过多。
  3. 频繁修改的数据修改后统一提交,而不是修改过后马上提交。
  4. 在不需要返回值的情况下,使用 apply() 方法可以极大的提高性能。
  5. 在跨进程通讯中不去使用 SharedPreferences ,可以使用 mmkv


参考链接

  1. 每日一问:谈谈 SharedPreferences 的 apply() 和 commit()
  2. 第一行代码:Android(第 2 版)