web-dev-qa-db-ja.com

Android SharedPreferences String Set-一部のアイテムはアプリの再起動後に削除されます

共有設定に文字列セットを保存します。それを読み込めば大丈夫です。私は他の活動を始め、戻ってそれをもう一度読みます、それは大丈夫です。アプリケーションを閉じて再度起動すると、セットが取得されますが、4個ではなく1個のアイテムのみが含まれます。これは常に発生します。既知の問題はありますか?何が間違っているのでしょうか?

クラスでは、アプリケーションのoncreateメソッドで作成されたものにSharedPreferences変数とSharePreferences.Editor変数があります。それらをsaveおよびloadメソッドで使用します。

public void saveFeedback(FeedbackItem feedbackItem) {
    checkSp();
    Set<String> feedbackSet = getFeedbacksSet();
    if(feedbackSet == null){
        feedbackSet = new HashSet<String>();
    }
    JSONObject json = createJSONObjectfromFeedback(feedbackItem);
    feedbackSet.add(json.toString());
    ed.putStringSet(CoreSetup.KEY_FEEDBACK, feedbackSet);
    ed.commit();
}

public Set<String> getFeedbacksSet(){
    checkSp();
    Set<String> ret = sp.getStringSet(CoreSetup.KEY_FEEDBACK, null);
    return ret;
}

private void checkSp(){
    if(this.sp == null)
        this.sp = applicationContext.getSharedPreferences(applicationContext.getPackageName(), Context.MODE_PRIVATE);
    if(this.ed == null)
        this.ed = this.sp.edit();
}

アプリの実行中にすべてのアイテムを完全に保存し、再起動後にすべてのアイテムがセットに含まれるわけではないため、どうすればそれが起こるのか理解できません。そして、すべてのアイテムが削除された場合、いくつかのアイテムが削除され、1つのアイテムがまだそこにあるよりも許容できると思います。説明はありますか?

32
user2313423

質問に基づいて、4つのアイテムがセットに追加された後にのみcommitを呼び出す必要があります。コードでは、フィードバックごとにコミットを呼び出して、以前のフィードバックを上書きします。

更新http://developer.Android.com/reference/Android/content/SharedPreferences.html#getStringSet(Java.lang。文字列 、Java.util.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.

これはまさにあなたがやっていることです

27
Madhur Ahuja

この「問題」は SharedPreferences.getStringSet() で文書化されています。

getStringSet()は、SharedPreferences内に格納されているHashSetオブジェクトの参照を返します。このオブジェクトに要素を追加すると、実際にはinsideSharedPreferencesに追加されます。

回避策は、返されたSetのコピーを作成し、新しいSetをSharedPreferencesに入れることです。私はそれをテストし、動作します。

コトリンでは、それは

    val setFromSharedPreferences = sharedPreferences.getStringSet("key", mutableSetOf())
    val copyOfSet = setFromSharedPreferences.toMutableSet()
    copyOfSet.add(addedString)

    val editor = sharedPreferences.edit()
    editor.putStringSet("key", copyOfSet)
    editor.apply() // or commit() if really needed
17
Jaden Gu

セットのコピーを作成してみてください。同じ設定で保存できます。

private Set<String> _setFromPrefs;


public void GetSetFromPrefs()
{
    SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
    Set<String> someSets = sharedPref.getStringSet("some_sets", new HashSet<String>() );
    _setFromPrefs = new HashSet<>(someSets); // THIS LINE CREATE A COPY
}


public void SaveSetsInPrefs()
{
    SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putStringSet("some_sets", _setFromPrefs);
    editor.commit();
}
7
Branko Riznić

これと同じ問題に遭遇しました。インスタンス化後、コミット前にエディターをクリアすることで解決しました。

sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    sFavList = sPrefs.getStringSet(context.getResources().getString(R.string.pref_fav_key), null);
    sEditor = sPrefs.edit();
    sEditor.clear(); // added clear, now Set data persists as expected
    if (sFavList == null) sFavList = new HashSet<>();
    sFavList.add(title);
    sEditor.putStringSet(context.getResources().getString(R.string.pref_fav_key), sFavList).apply();

他の人が示唆したようにコピーを作成しようとしましたが、それはうまくいきませんでした。

このソリューションを見つけました こちら

0
Dave Justen

ドキュメントによると、SharedPreferencesの文字列セットは不変として扱われるべきであり、変更しようとすると事態は南に向かっていきます。回避策は、既存のセットを取得し、そのコピーを作成し、コピーを更新してから、新しいセットのように共有設定に保存し直すことです。

Set<String> feedbackSet = getFeedbacksSet();
if(feedbackSet == null){
    feedbackSet = new HashSet<String>();
}

//make a copy of the set, update the copy and save the copy
Set<String> newFeedbackSet = new HashSet<String>();
JSONObject json = createJSONObjectfromFeedback(feedbackItem);
newFeedbackSet.add(json.toString());
newFeedbackSet.addAll(feedbackSet);
ed.putStringSet(CoreSetup.KEY_FEEDBACK, newFeedbackSet);
ed.commit();
0
s-hunter