安卓 - 共享首选项有时会丢失

24

我的应用程序的一些用户抱怨说,有时(随机的)我的应用程序设置会恢复到默认状态(通常是在手机重新启动后)。我从未成功重现过这个问题。我认为这可能是因为我的应用程序中许多地方都调用了shared preferences editor并提交了更改的代码块 - 如果我尝试同时提交对同一个preference文件的几次更改,是否会导致shared preference文件损坏?(多线程应用程序)

我真的很迷茫。我花了几个小时在网上寻找解决方案,但没有成功。

如果有人有任何想法,可以帮助我开始调查,我将不胜感激。

谢谢, Amit Moran


同步提交将是第一种方法。 - Kirill Rakhman
也许你在某个时候写了一个空键,这会在尝试加载首选项时清除它们 - 参见:https://dev59.com/cFXTa4cB1Zd3GeqP1GW7#19621603 - Mr_and_Mrs_D
5个回答

17

我会重复其他答案的建议 - 如果您不想破坏文件,需要避免冲突 - 我还要进一步建议您可能误用了SharedPreferences。

SharedPreferences旨在存储有关您的应用程序的小型信息 - 用户设置,例如音量或是否正在播放音乐等。

SharedPreferences不适用于存储经常更改和/或大量数据的数据,尝试这样做是一个坏主意(出于您发现的原因以及其他一些原因)。

请记住,SharedPreferences实际上只是一个XML文件 - 每次更改它时,您都会产生解析和重新创建的开销!

我认为,在多个线程中更新SharedPreferences的应用程序的想法有点疯狂 - 您需要更好的方法来管理和存储正在保存的数据 - 这将为您带来多种好处...


我想你是对的。我想我应该使用其他方式(比如SQLite)来处理高频率更改。我会尝试一下的。 - Amit Moran
好的,我已经测试过了。为了测试,我已经将重复更改的设置隔离出来,并将它们放在自己的共享首选项文件中。这样用户就不会一直使用更“稳定”的首选项文件。看起来这解决了问题。(我还在测试,但目前为止还不错)。如果我想在应用程序启动时保存数据,你有什么替代建议可以使用?(SQLite数据库会不容易受到损坏吗?) - Amit Moran
9
如果我需要经常更改设置或数据,我会将数据保存在内存中(在活动类或类似的对象中),并仅在 onPause() 方法中将其保存到 SharedPreferences 或数据库中,等等。频繁地向手机写入数据实际上没有任何好处 - 这通常非常慢(特别是写入 SD 卡)- 只需确保在应用程序暂停或其他情况下将其写入即可... - user834595

6
根据SharedPreferences.Editor文档

请注意,当两个编辑器同时修改首选项时,最后一个调用commit的编辑器会胜出。

从中可以得出,多个同时提交的操作不会清除您的首选项,但是如果同时使用多个Editor实例,则可能无法写入您尝试编写的所有更改。为避免这种情况,您可以将所有首选项修改放在同步块中,甚至可以使用一个同步静态方法来进行所有首选项编写。

3
是的,我看到了这份文档。我的问题是所有的偏好设置都回归到默认,而不是有些没有保存... - Amit Moran

1

我建议您使用单例来管理首选项。无论是通过实现true java singleton,还是使用Android的Application Context,都取决于您。(请参见this question,了解每种方法的优缺点)

对于像SharedPreferences这样的东西,这是一个很好的管理方式,特别是对于多线程应用程序。这可能会消除一些关于提交是否相互冲突的疑问。这可能不是整个问题,但这是一个开始。


我正在使用应用程序上下文... 但是在多线程应用程序中,它是否也是相同的上下文? - Amit Moran

0
我发现当打开编辑器,在没有对特定条目进行任何必要更改的情况下,只是进行了getString操作,然后在没有先通过putString对该条目进行更新的情况下直接commit,会导致该条目丢失。 一旦我插入了一个putString来保存该值,即使没有任何必要的更改,该条目也不再消失。

0
我曾经遇到过类似的问题:我的偏好设置无法可靠地保存。在某些设备上(比如我的XOOM平板电脑)数据有时会丢失,有时则不会。我通过在提交新数据之前简单地调用编辑器上的clear()方法来解决了这个问题。

在关闭设备或杀死应用程序后,共享偏好设置会丢失


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接