一句话说透Android里面的SharedPrefrences的apply和commit有什么区别

269 阅读2分钟

一句话总结:
commit 是“立刻交作业”,保证老师(系统)马上批改,但可能让你等半天;apply 是“先放讲台上”,老师有空再批改,不耽误你下课!


核心区别对比表

对比项commit()apply()
执行方式同步(立即写入磁盘)异步(先更新内存,后台写磁盘)
返回值✅ 返回 boolean(是否成功)❌ 无返回值
性能影响可能卡主线程(ANR 风险)不会卡主线程,更流畅
数据安全立即生效,崩溃前保证保存可能丢失数据(崩溃时未写入磁盘)
使用场景需要确保数据立刻保存(如关键配置)常规场景(如用户偏好设置)

详细解释(现实比喻)

1. commit() —— “立刻交作业”

  • 行为:调用 commit() 后,系统会立即将数据写入磁盘,主线程必须等写入完成才能继续执行。

  • 风险:如果数据量大或磁盘慢,主线程会被卡住,导致界面卡顿甚至 ANR。

  • 代码示例

    val editor = sharedPreferences.edit()  
    editor.putString("key", "value")  
    val isSuccess = editor.commit() // 同步等待写入完成  
    

2. apply() —— “先放讲台上”

  • 行为:调用 apply() 后,数据先更新到内存,然后系统在后台线程异步写入磁盘,主线程无需等待。

  • 优化:多个 apply() 调用会被合并为一次磁盘写入,减少 I/O 开销。

  • 代码示例

    val editor = sharedPreferences.edit()  
    editor.putString("key", "value")  
    editor.apply() // 异步写入,无阻塞  
    

实际场景选择指南

用 commit() 的场景

  • 关键数据保存:如用户支付结果、账户 Token,必须确保写入成功。
  • 需要处理结果:根据返回值判断是否保存成功。

用 apply() 的场景

  • 常规设置保存:如用户主题偏好、字体大小调整。
  • 高频调用:避免频繁 I/O 操作卡顿主线程。

避坑指南

  1. ANR 风险:在主线程大量调用 commit() 可能引发 ANR,务必用 apply()
  2. 数据丢失apply() 后若应用崩溃,数据可能未写入磁盘。关键数据改用 commit()
  3. 多进程问题SharedPreferences 不支持多进程,跨进程数据需用其他方式(如 ContentProvider)。

总结口诀

“commit 同步保安全,立刻写入不怕丢,
但卡主线程有风险,关键数据才需求。
apply 异步性能高,日常设置用它好,
崩溃可能丢数据,按需选择别混淆!”