commit() 是把内容同步提交到硬盘的,而 apply() 先立即把修改提交到内存,然后开启一个异步的线程提交到硬盘,并且如果提交失败,你不会收到任何通知。
所有 commit() 提交是同步过程,效率会比 apply() 异步提交的速度慢,在不关心提交结果是否成功的情况下,优先考虑 apply() 方法。
apply() 是使用异步线程写入磁盘,commit() 是同步写入磁盘。所以我们在主线程使用的 commit() 的时候,需要考虑是否会出现 ANR 问题。
我们每次添加键值对的时候,都会重新写入整个文件的数据,所以它不适合大量数据存储。
多线程场景下效率比较低,因为 get 操作的时候,会锁定 SharedPreferencesImpl 里面的对象,互斥其他操作,而当 put、commit() 和 apply() 操作的时候都会锁住 Editor 的对象,在这样的情况下,效率会降低。
由于每次都会把整个文件加载到内存中,因此,如果 SharedPreferences 文件过大,或者在其中的键值对是大对象的 JSON 数据则会占用大量内存,读取较慢是一方面,同时也会引发程序频繁 GC,导致的界面卡顿。
基于以上缺点:
建议不要存储较大数据到 SharedPreferences,也不要把较多数据存储到同一个 name 对应的 SharedPreferences 中,最好根据规则拆分为多个 SharedPreferences 文件。
频繁修改的数据修改后统一提交,而不是修改过后马上提交。
在跨进程通讯中不去使用 SharedPreferences。
获取 SharedPreferences 对象的时候会读取 SharedPreferences 文件,如果文件没有读取完,就执行了 get 和 put 操作,可能会出现需要等待的情况,因此最好提前获取 SharedPreferences 对象。
每次调用 edit() 方法都会创建一个新的 EditorImpl 对象,不要频繁调用 edit() 方法。
参考链接: