web-dev-qa-db-ja.com

Set <String> in Android sharedpreferencesは、強制終了時に保存されません

Androids sharedpreferencesを使用しようとしていますが、すべてをログに記録しました。以下のコードは実際に文字列セットをコミットします。問題は、アプリを強制的に閉じて再起動すると、settings.getStringSetが空のセットを返すことです。エラーメッセージはどこにもありません。

PreferenceManager.getDefaultSharedPreferencesを試しましたが、それも機能しません。

お時間をいただきありがとうございます。

public static final String PREFS_NAME = "MyPrefsFile";
private static final String FOLLOWED_ROUTES = "followedRoutes";

後で保存されたときに呼び出されます:

public void onFollowClicked(View view){

SharedPreferences settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();

Set<String> follows =  settings.getStringSet(FOLLOWED_ROUTES, new HashSet<String>());
follows.add(routeId);

editor.putStringSet(FOLLOWED_ROUTES, follows);
editor.commit();

}
21
Malin

見てください ここ

参考のためにも:

SharedPreferences

SharedPreferences.Editor

編集:

これには実際にはバグがあります。 ここ を参照してください。そこからの抜粋:

この問題は、17APIレベルでも引き続き発生します。

これは、SharedPreferencesクラスのgetStringSet()メソッドがSetオブジェクトのコピーを返さないために発生します。オブジェクト全体を返し、それに新しい要素を追加すると、SharedPrefencesImpl.EditorImplクラスのcommitToMemoryメソッドがそれを確認します。既存の値は、保存されている前の値と同じです。

この問題を回避する方法は、SharedPreferences.getStringSetによって返されるセットのコピーを作成するか、常に変更される他の設定(たとえば、毎回セットのサイズを格納するプロパティ)を使用してメモリへの書き込みを強制することです。

EDIT2:

解決策があるかもしれません ここ 、見てください。

19
g00dy

G00dyで言及されているバグを次のように回避することもできます。

SharedPreferencesからセットを取得し、変数に保存します。

次に、保存時に再度追加する前に、sharedpreferencesのセットを削除するだけです。

SharedPreferences.Editor editor= sharedPref.edit();
editor.remove("mSet");
editor.apply(); 
editor.putStringSet("mSet", mSet);
editor.apply();

必ずapply()またはcommit()を2回使用してください。

または、Kotlinで作業している場合は、次のようにします。

PreferenceManager.getDefaultSharedPreferences(applicationContext)
    .edit {
        this.remove("mSet")
        this.apply()
        this.putStringSet("mSet", mSet)
    }
32
Robbe