android मिसबिहेवियर जब शेयर्डप्रिफरेंस का उपयोग करके एक स्ट्रिंग सेट को स्टोर करने की कोशिश कर रहा है




android-preferences (4)

मैं SharedPreferences API का उपयोग करके स्ट्रिंग्स के एक सेट को संग्रहीत करने का प्रयास कर रहा हूं।

Set<String> s = sharedPrefs.getStringSet("key", new HashSet<String>());
s.add(new_element);

SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(s);
edit.commit()

पहली बार जब मैं ऊपर दिए गए कोड को निष्पादित करता हूं, तो डिफ़ॉल्ट मान पर सेट हो जाता है (बस बनाया गया खाली खाली HashSet ) और इसे बिना किसी समस्या के संग्रहीत किया जाता है।

दूसरी और अगली बार जब मैं इस कोड को निष्पादित करता हूं, तो एक s ऑब्जेक्ट पहले तत्व के साथ वापस आ जाता है। मैं तत्व जोड़ सकता हूं, और कार्यक्रम के निष्पादन के दौरान, यह जाहिरा तौर पर SharedPreferences में संग्रहित किया जाता है, लेकिन जब प्रोग्राम को मार दिया जाता है, तो SharedPreferences फिर से लगातार स्टोरेज से पढ़ता है और नए मान खो जाते हैं।

उसके बाद दूसरे, और तत्व कैसे संग्रहीत किए जा सकते हैं ताकि वे खो न जाएं?


एक ही मुद्दे के लिए एक समाधान के लिए खोज रहा था, द्वारा हल:

1) साझा वरीयताओं से मौजूदा सेट को पुनः प्राप्त करें

2) इसकी एक प्रति बनाएँ

3) कॉपी अपडेट करें

4) कॉपी को सेव करें

SharedPreferences.Editor editor = sharedPrefs.edit();
Set<String> oldSet = sharedPrefs.getStringSet("key", new HashSet<String>());

//make a copy, update it and save it
Set<String> newStrSet = new HashSet<String>();    
newStrSet.add(new_element);
newStrSet.addAll(oldSet);

editor.putStringSet("key",newStrSet); edit.commit();

Why


यह "समस्या" SharedPreferences.getStringSet पर SharedPreferences.getStringSet

SharedPreferences.getStringSet , SharedPreferences अंदर संग्रहीत HashSet ऑब्जेक्ट का संदर्भ देता है। जब आप इस ऑब्जेक्ट में तत्व जोड़ते हैं, तो वे वास्तव में SharedPreferences अंदर जोड़े जाते हैं।

यह ठीक है, लेकिन समस्या तब आती है जब आप इसे संग्रहीत करने का प्रयास करते हैं: एंड्रॉइड संशोधित HashSet की तुलना करता है जिसे आप SharedPreferences.Editor.putStringSet का उपयोग करके सहेजने की कोशिश कर रहे हैं, जो वर्तमान SharedPreference पर संग्रहीत है, और दोनों समान ऑब्जेक्ट हैं !!!

एक संभावित समाधान Set<String> की एक प्रतिलिपि बनाने के लिए है Set<String> SharedPreferences ऑब्जेक्ट द्वारा लौटाया गया:

Set<String> s = new HashSet<String>(sharedPrefs.getStringSet("key", new HashSet<String>()));

यह एक अलग वस्तु बनाता है, और s जोड़े गए तार साझा किए गए सेट के अंदर जोड़े नहीं जाएंगे।

अन्य वर्कअराउंड जो काम करेगा, उसी SharedPreferences.Editor लेन-देन का उपयोग एक और सरल वरीयता (पूर्णांक या बूलियन की तरह) को संग्रहीत करने के लिए किया जाता है, केवल एक चीज जिसकी आपको आवश्यकता है वह यह है कि संग्रहीत मूल्य प्रत्येक लेनदेन पर अलग हैं (उदाहरण के लिए, आप कर सकते हैं) स्ट्रिंग सेट का आकार स्टोर करें)।


मैंने उपरोक्त सभी उत्तरों की कोशिश की मेरे लिए कोई काम नहीं किया। इसलिए मैंने निम्नलिखित कदम उठाए

  1. पुराने साझा किए गए प्रीफ़ की सूची में नए तत्व को जोड़ने से पहले, उसकी एक प्रति बनाएं
  2. उपरोक्त विधि के साथ एक विधि को उस पद्धति के लिए एक पैराम के रूप में कहते हैं।
  3. उस पद्धति के अंदर साझा किए गए प्रीफ़ को साफ़ करें जो उस मान को पकड़े हुए हैं।
  4. प्रतिलिपि में मौजूद मानों को साझा की गई वरीयता के लिए इसे नए के रूप में माना जाएगा।

    public static void addCalcsToSharedPrefSet(Context ctx,Set<String> favoriteCalcList) {
    
    ctx.getSharedPreferences(FAV_PREFERENCES, 0).edit().clear().commit();
    
    SharedPreferences sharedpreferences = ctx.getSharedPreferences(FAV_PREFERENCES, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedpreferences.edit();
    editor.putStringSet(FAV_CALC_NAME, favoriteCalcList);
    editor.apply(); }

मैं मूल्यों के साथ निरंतर नहीं होने के कारण समस्या का सामना कर रहा था, अगर मैं ऐप को पृष्ठभूमि से ऐप को साफ करने के बाद फिर से सूची में जोड़ा गया पहला तत्व दिखाया गया था।


यह व्यवहार प्रलेखित है इसलिए यह डिजाइन द्वारा है:

getStringSet से:

"ध्यान दें कि आपको इस कॉल द्वारा लौटाए गए सेट इंस्टेंस को संशोधित नहीं करना चाहिए। संग्रहीत डेटा की संगतता की गारंटी नहीं है यदि आप करते हैं, और न ही आपके इंस्टेंस को बिल्कुल संशोधित करने की क्षमता है।"

और यह विशेष रूप से उचित लगता है यदि इसे एपीआई में प्रलेखित किया गया है, अन्यथा इस एपीआई को प्रत्येक एक्सेस पर प्रतिलिपि बनाना होगा। तो इस डिजाइन का कारण शायद प्रदर्शन था। मुझे लगता है कि उन्हें इस फ़ंक्शन रिटर्न परिणाम को अपरिवर्तनीय वर्ग उदाहरण में लपेटा जाना चाहिए, लेकिन इसके लिए एक बार फिर आवंटन की आवश्यकता होती है।





android-preferences