bookmark_border【SharedPreference】get/putStringSet()の罠挙動【Kotlin】

困ったこと

putStringSet()直後にアプリを再起動すると、getStringSet()の結果が空要素になる。(ならないときもある)

結論

getStringSet()で受け取ったSet<String>に対して要素の操作をしない。

まずいコード

getStringSet()で受け取ったSet<String>に要素を追加して、それをそのままputStringSet()する。

val set = sharedPreferences.getStringSet("hogehoge", mutableSetOf())
set.add("fugafuga")
sharedPreferences.edit().putStringSet("hogehoge", set).commit()
// setの要素数が0
val set = sharedPreferences.getStringSet("hogehoge", mutableSetOf())

改善

getStringSet()で受け取ったSet<String>を直接触らず、toMutableSet()で別Setを作ってそれを操作&putStringSet()する。

val set = sharedPreferences.getStringSet("hogehoge", mutableSetOf()).toMutableSet()
set.add("fugafuga")
sharedPreferences.edit().putStringSet("hogehoge", set).commit()

公式に書いてあった

getStringSet() で取得したSetの要素を操作しないようにとのこと。データの整合性(一貫性)はそもそも保証されない。

Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.

SharedPreferences | Android Developer