Skip to content

Shared Preferences

它是一个以XML格式提供持久化KV存储的安卓框架内置方案。

它由ContextImpl负责创建,进程内每个SharedPreference文件都会对应一个SharedPrefences实例。由此可以说,SharedPrefencesImpl实例在进程内和文件一对一存在。它多进程下无法保证安全。官方建议的跨进程访问需要使用ContentProvider,由此,它的mode参数已经基本无意义。

工作机理

这里我们主要讨论的是读取磁盘、和写入磁盘过程。如同很多涉及文件修改存储所用的技巧一样,sp会有一份备份文件,用于确保写入事务能原子完成。此技巧往往是在开始写入文件数据前,先对旧文件重命名。因为重命名是足够快的,此时再进行耗时的写入新文件过程。如果写入成功,此时会拥有两个文件,便再删除旧的重命名的文件即可。若写入失败,则这份重命名的旧文件将作为恢复点,即无论如何,不会导致整个文件处于不完整的修改状态,比如若在直接对原文件更新,更新了一半后失败了,那么文件会处于不可预料的状态。

在构建时会从磁盘读取,若备份文件存在,说明之前的写入是失败的。因为成功的写入会以删除备份文件作为结束。此时,会删除原文件,并把备份文件重命名为原文件。

在写入任务时,会先把原文件重命名为备份文件名,然后以最新的map数据写入原文件(此时意味着创建了一个新文件,名字和原文件名相同)。成功后再删除备份文件即可。由此结合上面所述逻辑,可以确保对文件的更改是原子性的。

sp使用了很多synchronize代码块(不是直接修饰方法),来确保多线程同步。此外,apply和commit分别异步/同步把变更写回到文件。

拓展阅读