我在生产中遇到这个烦人的错误,导致我的应用崩溃。
我做PreferenceManager.getDefaultSharedPreferences(context).edit().putLong("key", value).apply();
来保存许多基于用户的偏好设置
我正在使用implementation 'androidx.preference:preference:1.0.0'
但仍然有很多
Fatal Exception: java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry + 851(HashMap.java:851)
at java.util.HashMap$KeyIterator.next + 885(HashMap.java:885)
at com.android.internal.util.XmlUtils.writeSetXml + 355(XmlUtils.java:355)
at com.android.internal.util.XmlUtils.writeValueXml + 693(XmlUtils.java:693)
at com.android.internal.util.XmlUtils.writeMapXml + 300(XmlUtils.java:300)
at com.android.internal.util.XmlUtils.writeMapXml + 269(XmlUtils.java:269)
at com.android.internal.util.XmlUtils.writeMapXml + 235(XmlUtils.java:235)
at com.android.internal.util.XmlUtils.writeMapXml + 192(XmlUtils.java:192)
at android.app.SharedPreferencesImpl.writeToFile + 639(SharedPreferencesImpl.java:639)
at android.app.SharedPreferencesImpl.-wrap2(SharedPreferencesImpl.java)
at android.app.SharedPreferencesImpl$2.run + 535(SharedPreferencesImpl.java:535)
at java.util.concurrent.ThreadPoolExecutor.runWorker + 1133(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run + 607(ThreadPoolExecutor.java:607)
at java.lang.Thread.run + 761(Thread.java:761)
我确实知道我的许多首选项更改都发生在后台线程中,但是android api应该同步了吗?
我不知道哪些更改会导致崩溃,因为当它在android API中的分离线程中运行时,我无法获取有关崩溃的更多信息
有人知道这是什么吗?如何解决而不将所有apply
变成commit
的情况?如何获取更多信息?
答案 0 :(得分:1)
我也遇到了这个问题,但是事实证明,Shared Prefs本身没有线程安全问题,这显然是线程安全的(请参阅https://regex101.com/r/25qa84/1)
问题原来是传递到SharedPreferences.Editor.putStringSet()中的Set
。如果您传递了Set
,然后在SharedPreferences迭代写入它的确切时间修改了Set
,它将引发此错误。
为避免这种情况,请复制Set
并将其传递给putStringSet()
答案 1 :(得分:-1)
apply():异步
commit():同步
使用commit()而不是apply()解决问题。
PreferenceManager.getDefaultSharedPreferences(context).edit().putLong("key", value).commit();
commit()会同步写入数据(阻止从其调用的线程)。然后它会通知您该操作成功。
apply()安排异步写入数据。它不会通知您有关操作成功的信息。