共享首选项中commit()和apply()之间的区别是什么

And*_*lva 412 android sharedpreferences

我在我的Android应用程序中使用共享首选项.我正在使用共享偏好中的两者commit()apply()方法.当我使用AVD 2.3时它没有显示错误,但是当我在AVD 2.1中运行代码时,apply()方法显示错误.那么这两者有什么区别?通过使用commit()我只能存储偏好值没有任何问题?

Ray*_*ton 626

apply()在2.3中添加,它提交时返回表示成功或失败的布尔值.

commit()如果保存工作则返回true,否则返回false.

apply() 因为Android开发团队注意到几乎没有人注意到返回值,所以应用程序更快,因为它是异步的.

http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply()

  • commit()立即将其数据写入持久存储,而apply()将在后台处理它. (54认同)
  • 如果我用apply()写一些东西并尝试在之后立即读取它会发生什么?读保证是否能给我最新的价值?文档说,如果在激活apply()之后发生了另一个commit(),那么commit()将阻塞,直到apply()持久化到磁盘,这清楚地表明当涉及'write'操作时不会发生这个问题,但如果你之后立即写作和阅读呢?从我的测试中,返回了最新的值,但我想知道这是否是100%保证. (39认同)
  • 用apply()替换commit()的任何实例是安全的,请参阅http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply() (22认同)
  • 它会造成竞争条件吗? (18认同)
  • 这个答案是对的,但我猜@spacemanaki上面的评论也是真实的,包含有价值的信息 (7认同)
  • @Tiago,基于https://github.com/android/platform_frameworks_base/blob/master/core/java/android/app/SharedPreferencesImpl.java,它看起来像是将写入应用于稍后写入磁盘的地图,并使用方法像getInt从该地图中获取int. (7认同)
  • @Tiago 我认为文档的这一部分将消除您的疑虑。`与将其首选项同步写入持久存储的 commit() 不同,apply() 立即将其更改提交到内存中的 SharedPreferences,但会启动对磁盘的异步提交,并且您不会收到任何失败通知。 (2认同)
  • 仅需额外支付2美分......我唯一一次将此视为一个问题是应用程序"重新启动".(通常是在开发环境中重建应用程序)重新启动的应用程序版本将有一个由错误信息构建的共享首选项的新实例. (2认同)
  • @BitcoinCash-ADAenthusiast我知道现在评论已经太晚了,但根据文档“apply() 立即将其更改提交到内存中的 SharedPreferences,但启动异步提交到磁盘”。因此,一旦您提交并尝试读取,您就会从内存中的 SharedPreferences 中获取最新值。 (2认同)

Luk*_*uth 207

TL;博士:

  • commit()同步写入数据(阻止调用它的线程).然后它会通知您操作的成功.
  • apply()调度要异步写入的数据.它不会告诉您操作是否成功.
  • 如果您保存apply()立即通过任何getX方法读取,将返回值!
  • 如果你apply()在某个时刻调用它仍在执行,那么任何调用commit()都会阻塞,直到所有过去的apply-calls 当前的commit-call完成.

来自SharedPreferences.Editor文档的更深入信息:

commit()同步地将其首选项写入持久存储,apply()会立即将其更改提交到内存中的SharedPreferences,但会启动异步提交到磁盘,并且不会通知您任何失败.如果此SharedPreferences上的另一个编辑器在apply()尚未完成时执行常规commit(),则commit()将阻塞,直到完成所有异步提交以及提交本身.

由于SharedPreferences实例是进程中的单例,因此如果您已经忽略了返回值,则可以使用apply()替换commit()的任何实例.

SharedPreferences.Editor接口不应直接实现.但是,如果您之前已实现它并且现在收到有关缺少apply()的错误,则只需从apply()调用commit()即可.

  • 这是一个更好的答案,因为它提到`apply()`是异步的,挂起的写入阻止将来调用`commit()`. (17认同)

Jos*_*ura 22

我在使用apply()而不是commit()时遇到了一些问题.如前面在其他响应中所述,apply()是异步的.我遇到的问题是,对"字符串集"首选项形成的更改永远不会写入持久性内存.

如果您"强行扣留"程序,或者在我使用Android 4.1安装在我的设备上的ROM中,当系统由于内存需要而导致该进程被终止时,就会发生这种情况.

如果您希望自己的偏好存活,我建议使用"commit()"而不是"apply()".


Mus*_*afa 14

使用apply().

它立即将更改写入RAM并等待并将其写入内部存储(实际首选项文件)之后.Commit将更改同步并直接写入文件.


Moj*_*sin 13

该文档给出的区别的一个很好的解释apply()commit():

commit()将其首选项同步写入持久存储的情况不同,apply()它会SharedPreferences立即将其更改提交到内存中 ,但会启动异步提交到磁盘,并且不会通知您任何故障.如果另一个编辑器SharedPreferences执行常规commit()而a apply()仍然未完成,commit()则将阻塞,直到完成所有异步提交以及提交本身.由于SharedPreferences实例是进程中的单例commit(),apply()如果您已经忽略了返回值,则可以安全地替换with的任何实例 .


Nur*_*yev 13

  • commit()是同步的,apply()是异步的

  • apply() 是无效的功能.

  • commit() 如果新值已成功写入持久存储,则返回true.

  • apply() 在切换状态之前保证完整,您不必担心Android组件的生命周期

如果你不使用来自返回值commit()和你使用commit()的主线程,使用apply()替代 commit()


Cha*_*ghe 12

\n

commit() 和 apply() 之间的区别

\n
\n\n

当我们使用 SharedPreference 时,我们可能会对这两个术语感到困惑。基本上它们可能是相同的,所以让\xe2\x80\x99s澄清commit()和apply()的区别。

\n\n
\n

1.返回值:

\n
\n\n

apply()提交而不返回指示成功或失败的布尔值。\n commit() 如果保存有效则返回 true,否则返回 false。

\n\n
\n
    \n
  1. 速度:
  2. \n
\n
\n\n

apply()更快。\ncommit()更慢。

\n\n
\n
    \n
  1. 异步与同步:
  2. \n
\n
\n\n

apply(): 异步\n commit(): 同步

\n\n
\n
    \n
  1. 原子:
  2. \n
\n
\n\n

apply(): 原子\n commit(): 原子

\n\n
\n
    \n
  1. 错误通知:
  2. \n
\n
\n\n

apply(): 否\n commit(): 是

\n


Vla*_*nov 6

来自javadoc:

与commit()同步地将其首选项写入持久存储,apply()会立即将其更改提交到内存中的SharedPreferences,但会启动异步提交到磁盘,并且不会通知您任何失败.如果此SharedPreferences上的另一个编辑器执行常规commit()而> apply()仍未完成,则commit()将阻塞,直到完成所有异步提交以及提交本身