2009-10-28 13 views
21

मैं एक जावा बीन वस्तु जो serializable है कहो। मैं() एक गतिविधि OnDestroy माध्यम से चला जाता है जब यह दूर स्टोर करने के लिए सुरक्षित रूप से उद्देश्य पर (अर्थात onSaveInstanceState() नहीं कहा जाता है)।मैं गतिविधि पुनरारंभ भर में एक जटिल वस्तु कैसे बचाऊं?

मैं ऐसे तरीके की तलाश में हूं जिसमें डेटाबेस बनाने और ऑब्जेक्ट को लिखने में शामिल नहीं है (ज्यादातर तब से) एंड्रॉइड के डीबी एपीआई भयानक है और बी) चूंकि डेटाबेस एप्लिकेशन को दुःस्वप्न अपडेट करता है, क्योंकि कोई सभ्य नहीं है माइग्रेशन लागू करने के लिए समर्थन)।

मैं एक ByteArrayOutputStream करने के लिए वस्तु serializing बेस 64 एन्कोड कि और एक स्ट्रिंग के रूप में एक SharedPreferences फाइल करने के लिए इसे लिखने के बारे में सोचा। या वह बहुत दूर है?

अद्यतन

हो सकता है कि serialize-से-स्ट्रिंग विचार सब के बाद इतना बुरा नहीं था, बहुत अच्छी तरह से बाहर काम करने लगता है। यहाँ अब मैं क्या कर रहा है:

public static String objectToString(Serializable object) { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    try { 
     new ObjectOutputStream(out).writeObject(object); 
     byte[] data = out.toByteArray(); 
     out.close(); 

     out = new ByteArrayOutputStream(); 
     Base64OutputStream b64 = new Base64OutputStream(out); 
     b64.write(data); 
     b64.close(); 
     out.close(); 

     return new String(out.toByteArray()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

public static Object stringToObject(String encodedObject) { 
    try { 
     return new ObjectInputStream(new Base64InputStream(
       new ByteArrayInputStream(encodedObject.getBytes()))).readObject(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 
OnDestroy में

() मैं तो बस एक वरीयता फ़ाइल है, जहां यह सुरक्षित है जब तक मैं इसे फिर से अगले गतिविधि लॉन्च के दौरान पढ़ने के लिए Base64 स्ट्रिंग लिख सकते हैं। यह मेरी अपेक्षा से बहुत तेज़ है और जब तक कि आपके सेम में बड़ी मात्रा में डेटा नहीं है, यह बहुत अच्छी तरह से काम करता है। और इससे भी बेहतर, आपको डीबी स्कीमा को बनाए रखने की ज़रूरत नहीं है।

फिर भी, मैं के बारे में कैसे दूसरों को ऐसा करने के उत्सुक हूँ।

+0

यह सिर्फ बजाय बंडल का उपयोग करना संभव नहीं है? – JRL

+0

कैसे? यदि आप अपनी गतिविधि SaveInstanceState() पर जाते हैं, तो आप केवल बंडल तक पहुंच सकते हैं, यानी जब इसे रनटाइम द्वारा नष्ट किया जा रहा है। – Matthias

+0

बहुत बढ़िया! मैंने आपका दृष्टिकोण इस्तेमाल किया और यह काम करता है। केवल एंड्रॉइड एसडीके में बेस 64InputStream में केवल एक मुद्दा है जिसमें एक कन्स्ट्रक्टर नहीं है जिसमें एक पैरामीटर है जिसमें अब एक अतिरिक्त int ध्वज पैरामीटर है। यदि आपके पास ऑब्जेक्ट में कोई यूआरएल जानकारी है तो बस इसे 0 या 8 पर सेट करें। – JPM

उत्तर

9

मैं एक तरह से जो एक डेटाबेस है कि (ज्यादातर के बाद से एक) Android के डीबी एपीआई भयानक है और ख) के बाद से डेटाबेस बनाने के आवेदन एक अद्यतन करता है करने के लिए वस्तु बनाने शामिल है और लिखने नहीं रहा हूँ बुरा सपना है, क्योंकि माइग्रेशन लागू करने के लिए कोई सभ्य समर्थन) होती है।

एंड्रॉइड का एपीआई वास्तव में काफी उचित है, क्योंकि ज्यादातर SQLite एपीआई पर एक पतला आवरण है, और SQLite API एक एम्बेडेड डेटाबेस के लिए काफी उचित है। इसके अलावा, एंड्रॉइड SQLiteOpenHelper के माध्यम से ऐप अपग्रेड पर स्कीमा अपग्रेड के लिए सहायता प्रदान करता है।

यह जब तक आपके सेम भारी मात्रा में डेटा की , यह बहुत अच्छी तरह से काम करता है ले जाने के बहुत तेजी से मेरी अपेक्षा से और है।

मैंने सुना है कि लोगों के साथ लंबी अवधि की सफलता के बारे में मैंने सुना है कि मैंने कई और डेवलपर्स को धारावाहिकता से चिल्लाते हुए भाग लिया है। पिछले कुछ दिनों में, यहां SO #android पर, मेरे पास जड़ से अपने ऐप से सीरियलाइजेशन को पिसाने के लिए सख्त कोशिश कर रहा था।

और इससे भी बेहतर, आपको डीबी स्कीमा को बनाए रखने की आवश्यकता नहीं है।

अरे हाँ आप कर सकते हैं। जब आप अपना आवेदन अपडेट करते हैं और आपकी कक्षा संशोधित होती है तो आपको क्या लगता है? bookkeeping कर यह पता लगाने की एक वर्ग का एक नया संस्करण से वर्ग के पुराने संस्करणों deserialize करने के लिए कैसे एक घर का काम है और कारणों डेवलपर्स क्रमबद्धता का परित्याग से एक है।साथ ही, यह न भूलें कि धारावाहिक लेनदेन नहीं है, जबकि SQLite है।

+1

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

+5

प्रत्येक के लिए। – CommonsWare

+0

मैथियस विधि बहुत बढ़िया काम करती है यदि आप एक जटिल वस्तु को सहेज रहे हैं और किसी ऑब्जेक्ट पर प्रत्येक डेटापॉइंट के लिए सभी कॉलम को परिभाषित करने की परेशानी से गुजरना नहीं चाहते हैं। – JPM

3

मैं किसी भी बीन्स या गतिविधि राज्यों को अन/marshalling का एक अच्छा दृष्टिकोण भी तलाश रहा था। हम सभी जानते हैं कि onStoreInstanceState() और onRestoreInstanceState() पर गतिविधि कितनी दर्द है।

मेरी उत्तेजनाएं बस अपने राज्यों को ऑन-ऑन() में संग्रहीत करती हैं और उन्हें सीधे ऑब्जेक्ट क्रमबद्धता के माध्यम से क्रिएट() लाइफसाइकिल हुक में पुनर्स्थापित करती हैं।

आपके जैसे स्ट्रिंग के माध्यम से सीरियलाइजेशन, निश्चित रूप से संभव है लेकिन बड़े डेटा के लिए कम उपयुक्त है और बहुत अधिक ओवरहेड का कारण बनता है। इसके अलावा प्राथमिकताएं वरीयताओं को स्टोर करने के लिए वास्तव में हैं, डेटा नहीं :) दुर्भाग्यवश, पार्ससेलबल/पार्सल जो हम इस उद्देश्य के लिए उपयोग कर सकते हैं, लगातार भंडारण को स्टोर करने की अनुशंसा नहीं करता है।

तो क्या बचा है एक साधारण वस्तु क्रमबद्धता है - जैसे हम भी एक गैर एंड्रॉयड जावा दुनिया में क्या करना होगा, एक सरल - सौभाग्य एंड्रॉयड एसडीके सभी कमियां और लाभ के साथ ObjectInputStream और ObjectOutputStream वर्गों के कार्यान्वयन है:

ContextWrapper - - गतिविधि है, जो स्थानीय कैश करने के लिए बहुत उपयोगी होते हैं
ObjectOutputStream.writeObject(yourPojo) 

हमारे लिए जादू करना होगा,

इसके अलावा (Serializable मार्कर-इंटरफ़ेस को लागू करने के लिए याद), आप एक संदर्भ के एपीआई निम्नलिखित में देखने के लिए चाहते हो सकता है डेटा (जैसे छवियां) आदि:

.getCacheDir() 
.getDir() 
.openFileInput() 
.openFileOutput() 

खुश हैकिंग :)

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