一句话总结:
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 操作卡顿主线程。
避坑指南
- ANR 风险:在主线程大量调用
commit()可能引发 ANR,务必用apply()。 - 数据丢失:
apply()后若应用崩溃,数据可能未写入磁盘。关键数据改用commit()。 - 多进程问题:
SharedPreferences不支持多进程,跨进程数据需用其他方式(如 ContentProvider)。
总结口诀
“commit 同步保安全,立刻写入不怕丢,
但卡主线程有风险,关键数据才需求。
apply 异步性能高,日常设置用它好,
崩溃可能丢数据,按需选择别混淆!”