SharedPreferences正确使用
-
不要存放大的 key 和 value 在 SharedPreferences 中,否则会一直存储在内存中得不到释放,内存使用过高会频发引发GC,导致界面丢帧甚至ANR。
-
不相关的配置选项最好不要放在一起,单个文件越大读取速度则越慢。
-
读取频繁的 key 和不频繁的 key 尽量不要放在一起(如果整个文件本身就较小则忽略,为了这点性能添加维护得不偿失)。
-
不要每次都edit,因为每次都会创建一个新的EditorImpl对象,最好是批量处理统一提交。否则 edit().commit 每次创建一个新的 EditorImpl 对象并且进行一次 I/O 操作,严重影响性能。
-
commit 发生在 UI 线程中,apply 发生在工作线程中,对于数据的提交最好是批量操作统一提交。虽然apply 发生在工作线程(不会因为IO阻塞UI线程)但是如果添加任务较多也有可能带来其他严重后果(参照ActivityThread源码中handleStopActivity方法实现)。
-
尽量不要存放 JSON 和 HTML,这种可以直接文件缓存。
-
不要指望这货能够跨进程通信 Context.PROCESS 。
-
最好提前初始化 SharedPreferences,避免 SharedPreferences 第一次创建时读取文件线程未结束而出现等待情况。
-
SharedPreferences 是线程安全的. 内部由大量 synchronized 关键字保障
-
SharedPreferences 不是进程安全的
-
第一次 getSharedPreferences 会读取磁盘文件, 后续的 getSharedPreferences 会从内存缓存中获取. 如果第一次调用 getSharedPreferences 时还没从磁盘加载完毕就调用 getXxx/putXxx , 则 getXxx/putXxx 操作会卡主, 直到数据从磁盘加载完毕后返回
-
所有的 getXxx 都是从内存中取的数据
-
apply 是同步回写内存, 然后把异步回写磁盘的任务放到一个单线程的队列中等待调度. commit 和前者一样, 只不过要等待异步磁盘任务结束后才返回
-
MODE_MULTI_PROCESS 是在每次 getSharedPreferences 时检查磁盘上配置文件上次修改时间和文件大小, 一旦所有修改则会重新从磁盘加载文件. 所以并不能保证多进程数据的实时同步
-
从 Android N 开始, 不再支持 MODE_WORLD_READABLE & MODE_WORLD_WRITEABLE. 一旦指定, 会抛异常
-
多次 getSharedPreferences 几乎是没有代价的.