android 在SharedPreferences中commit()和apply()有什么区别

9gm1akwq  于 2023-01-24  发布在  Android
关注(0)|答案(9)|浏览(273)

我在我的Android应用程序中使用SharedPreferences。我使用共享首选项中的commit()apply()方法。当我使用AVD 2.3时,它显示没有错误,但当我在AVD 2.1中运行代码时,apply()方法显示错误。
那么这两者之间的区别是什么呢?通过只使用commit(),我可以毫无问题地存储首选项值吗?

a11xaf1n

a11xaf1n1#

apply()是2.3中添加的,它提交而不返回指示成功或失败的布尔值。
commit()返回
true**(如果保存成功),否则返回false
添加apply()是因为Android开发团队注意到几乎没有人注意到返回值,因此apply速度更快,因为它是异步的。
http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply()

uemypmqf

uemypmqf2#

TL;医生:

  • commit()同步写入数据(阻塞调用它的线程),然后通知您操作成功。
  • apply()调度要异步写入的数据。它不会通知您操作成功。
  • 如果使用apply()保存,并且通过任何getX方法立即读取,则将返回值!
  • 如果您在某个时候调用了apply(),并且它仍在执行,则对commit()的任何调用都将阻塞,直到所有过去的apply-call * 和 * 当前的commit-call完成为止。

SharedPreferences.Editor文档中的更多详细信息:
提交不同(),它将其首选项同步写出到持久性存储应用()立即将其更改提交到内存中的SharedPreferences,但会启动到磁盘的异步提交,并且不会通知您任何失败。如果此SharedPreferences上的另一个编辑器执行常规提交()当apply()仍然未完成时,commit()将阻塞,直到所有异步提交以及提交本身完成。
由于SharedPreferences示例是进程中的单例,因此如果您已经忽略了返回值,则可以安全地将commit()的任何示例替换为apply()。
SharedPreferences.Editor接口不应该直接实现,但是,如果你之前实现了它,现在又收到了关于缺少apply()的错误,你可以简单地从apply()调用commit()。

rlcwz9us

rlcwz9us3#

我在使用apply()而不是commit()时遇到了一些问题。正如之前在其他回复中所述,apply()是异步的。我遇到的问题是,对“字符串集”首选项所做的更改永远不会写入持久性内存。
它发生,如果你“强制拘留”的程序,或者,在ROM中,我已经安装在我的设备与Android 4.1,当进程被系统杀死,由于内存的必要性.
如果您希望您的首选项保持活跃,我建议使用“commit()”而不是“apply()”。

nqwrtyyt

nqwrtyyt4#

使用apply()。
它会立即将更改写入RAM,然后等待并将其写入内部存储(实际的首选项文件)。Commit会同步地将更改直接写入文件。

o2gm4chl

o2gm4chl5#

  • commit()为同步,apply()为异步
  • apply()是空函数。
  • 如果新值成功写入持久存储,则commit()返回true。
  • apply()保证在切换状态之前完成,您无需担心Android组件的生命周期

如果不使用从commit()返回的值,而是使用主线程中的commit(),请使用apply()而不是commit()

rkue9o1l

rkue9o1l6#

这些文档很好地解释了apply()commit()之间的区别:
commit()不同的是,apply()会将其首选项同步写入持久存储,apply()会立即将其更改提交到内存中的SharedPreferences,但会启动一个异步提交到磁盘,并且不会通知您任何失败。如果SharedPreferences上的另一个编辑器执行常规commit(),而apply()仍然未完成,commit()将被阻塞,直到所有异步提交以及提交本身都完成。由于SharedPreferences示例是进程中的单例,如果您已经忽略了返回值,则可以安全地用apply()替换commit()的任何示例。

8i9zcol2

8i9zcol27#

commit()和apply()之间的区别
当我们使用SharedPreference时,我们可能会被这两个术语搞混。基本上,它们可能是相同的,所以让我们澄清commit()和apply()的区别。
1.返回值:
apply()提交时不返回指示成功或失败的布尔值。如果保存成功,commit()返回true,否则返回false。
1.速度:
apply()比较快。commit()比较慢。
1.异步与同步:
apply():异步commit():同步
1.原子:
x一m六n一x:原子x一m七n一x:原子的
1.错误通知:
apply():否commit():是的

s4n0splo

s4n0splo8#

来自javadoc:
与提交不同()将其首选项同步写出到持久性存储,适用()立即将其更改提交到内存中的SharedPreferences,但启动异步提交到磁盘,并且不会通知您任何失败。如果此SharedPreferences上的另一个编辑器执行常规提交()当a〉apply()仍然未完成时,commit()将阻塞,直到所有异步提交以及提交本身完成为止

jaxagkaj

jaxagkaj9#

在使用Web API时,我注意到在注销前使用共享首选项时apply()的主要缺点。
请看下面的场景:用户登录并通过POST传递令牌(用于自动重新登录)。

SharedPreferences preferences = App.getContext().getSharedPreferences("UserCredentials", Context.MODE_PRIVATE);

SharedPreferences.Editor editor = preferences.edit();

editor.putString("TOKEN",token);

editor.apply();

令牌在所有会话中可用,没有问题,自动重新记录完成,在所有状态中没有任何进一步的问题。
在编写logout函数时,我清除了共享首选项,如下所示

SharedPreferences preferences = App.getContext().getSharedPreferences("UserCredentials", Context.MODE_PRIVATE);

SharedPreferences.Editor editor = preferences.edit();

editor.clear();

editor.apply()

简而言之,你可以简单地写为:

preferences.edit().clear().apply()

为了确保清除该高速缓存,我将在注销前登录,preferences.getString("TOKEN");显示为null
在重新启动主活动之后(因为它是从登录片段开始的)-我将使用以下命令再次检查令牌:

SharedPreferences preferences = App.getContext().getSharedPreferences("UserCredentials", MODE_PRIVATE);
        
String retrievedToken = preferences.getString("TOKEN",null); // Second param = default value

Log.d(TAG, "RETRIEVING TOKEN: " + retrievedToken);

令牌实际上重新出现,尽管在注销之前令牌肯定已被清除。
(导致注销-〉'使用令牌登录循环)
只有在将editor.commit();添加到设置和清除令牌之后,令牌才会真正永久消失。
请注意,我使用了模拟器。
这种行为实际上是有意义的,因为内存中的存储被更新,但异步调用在应用程序重新启动之前从未进行过。
因此,commit();将强制应用程序等待(同步)实际的后续命令,如system.exit()等,而apply()很可能失败,如果其他命令将强制应用程序中的特定状态更改。
为了确保您能找到所有正确的地方,您可以始终使用apply()和commit()。

相关问题