2012-12-25 26 views
51

मैं 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() 

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

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

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

+1

कोड को editor.putStringSet() को कॉल नहीं करना चाहिए? – bluehallu

उत्तर

118

यह "समस्या" SharedPreferences.getStringSet पर प्रलेखित है।

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

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

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

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

सम्भावित समाधान Set<String>SharedPreferences वस्तु द्वारा वापस की एक प्रतिलिपि बनाने के लिए है SharedPreferences

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

+3

मैं पहले से ही +1 कर चुका हूं लेकिन क्या आप अपने दावे का समर्थन करने वाले स्रोत को एक लिंक प्रदान कर सकते हैं: "एंड्रॉइड संशोधित हैशसेट की तुलना करता है जिसे आप SharePreferences.Editor.putStringSet का उपयोग करके सहेजने की कोशिश कर रहे हैं। SharePreference" –

+1

बीन पर संग्रहीत वर्तमान के साथ इस दिन एक दीवार के खिलाफ मेरे सिर को टक्कर लगी! धन्यवाद!!! – Tim

+0

दूसरा विकल्प (काउंटर सहेजें) मेरे लिए ठीक काम करता है। धन्यवाद! – MarionaDSR

12

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

getStringSet से

:।

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

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

+2

मैंने आज दोपहर अपना जवाब संपादित किया। मुझे एहसास हुआ कि यह सही ढंग से प्रलेखित है, लेकिन जब आप कई बार कोड लिख रहे हैं तो आप इस तरह की चीजों में दस्तावेज़ीकरण को नहीं देखते हैं। यह पूछने का एकमात्र कारण है + उत्तर, आईएमएचओ, क्योंकि यह एक उपयोगिता वर्ग है और इस तरह की स्पष्टीकरण किसी की भी मदद कर सकती है। आपकी स्पष्टीकरण के लिए भी धन्यवाद – JoseLSegura

2

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

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

0

मैंने उपर्युक्त उत्तरों की कोशिश की, मेरे लिए कोई भी काम नहीं किया। तो मैं निम्न चरणों के

  1. किया पुराने साझा वरी की सूची में नए तत्व जोड़ने से पहले, इसकी एक प्रति
  2. कॉल कि विधि करने के लिए एक परम के रूप में ऊपर की नकल के साथ एक विधि बना दें।
  3. उस विधि के अंदर उस मूल्य को साझा करने वाले साझा किए गए pref को साफ़ करें।
  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(); } 
    

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

संबंधित मुद्दे