डेटा को बनाए रखने के लिए Android एप्लिकेशन वर्ग का उपयोग करना


112

मैं एक काफी जटिल एंड्रॉइड एप्लिकेशन पर काम कर रहा हूं जिसके लिए एप्लिकेशन के बारे में कुछ बड़ी मात्रा में डेटा की आवश्यकता होती है (मैं कुल 500KB के बारे में कहूंगा - यह एक मोबाइल डिवाइस के लिए बहुत बड़ा है?)। मैं जो बता सकता हूं, वह अनुप्रयोग में किसी भी अभिविन्यास परिवर्तन (गतिविधि में, अधिक सटीक होने के लिए) गतिविधि के पूर्ण विनाश और मनोरंजन का कारण बनता है। मेरे निष्कर्षों के आधार पर, आवेदन वर्ग में एक ही जीवन-चक्र नहीं है (अर्थात, यह सभी उद्देश्यों और उद्देश्यों के लिए है, हमेशा त्वरित रूप से)। क्या यह एप्लिकेशन क्लास के अंदर राज्य की जानकारी को संग्रहीत करने और फिर गतिविधि से संदर्भित करने के लिए समझ में आता है, या क्या यह आम तौर पर मोबाइल उपकरणों पर मेमोरी बाधाओं के कारण "स्वीकार्य" विधि नहीं है? मैं वास्तव में इस विषय पर किसी भी सलाह की सराहना करता हूं। धन्यवाद!


8
बस ध्यान रखें कि यदि आपका ऐप बैकग्राउंड में चला जाता है, तो आपके एप्लिकेशन का डेटा अभी भी डिलीट किया जा सकता है, इसलिए यह उन स्थायी डेटा का समाधान नहीं है जिन्हें आप हमेशा वापस पाने में सक्षम होना चाहते हैं। यह सिर्फ महंगी वस्तुओं को अक्सर के रूप में फिर से बनाने के लिए नहीं की एक विधि के रूप में कार्य करता है।
चेरिल सिमोन 20

2
मायरा; मुझे नहीं लगता कि एप्लिकेशन "आमतौर पर" हटा दिया गया है (हालांकि, जैसा कि किसी ने इस धागे में बाद में बताया है, यह "हो सकता है")। मैं शायद डेटा को स्टोर करने और लोड करने के लिए एप्लिकेशन का उपयोग करने के कुछ "हाइब्रिड" दृष्टिकोण के साथ जा रहा हूं, लेकिन फिर सामान्य फ़ाइल को ओवरराइड करने के लिए मैनिफ़ेस्ट फ़ाइल में गतिविधि पर "एंड्रॉइड: ओरिएंटेशन" विशेषता का उपयोग करें। नीचे फाड़ और गतिविधि के पुनर्निर्माण। यह सब, निश्चित रूप से, मानता है कि एप्लिकेशन "तब" निर्धारित कर सकता है जब इसे नष्ट किया जा रहा है ताकि डेटा को बनाए रखा जा सके।
डेव

जवाबों:


134

मुझे नहीं लगता कि 500kb एक बड़ी डील होगी।

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

यदि आप बहुत अधिक उपयोग करने जा रहे हैं तो आप किसी ग्लोबल सिंगलटन में डेटा पास कर सकते हैं।

public class YourApplication extends Application 
{     
     public SomeDataClass data = new SomeDataClass();
}

फिर इसे किसी भी गतिविधि में कॉल करें:

YourApplication appState = ((YourApplication)this.getApplication());
appState.data.UseAGetterOrSetterHere(); // Do whatever you need to with the data here.

मैं यहाँ अपने ब्लॉग पोस्ट में इस पर चर्चा करता हूं , "ग्लोबल सिंगलटन" के सेक्शन के तहत।


1
दुर्भाग्य से प्रश्न में ब्लॉग पोस्ट अब उस पते पर उपलब्ध नहीं है।
माइकबाकॉक

1
मैं अपनी साइट पर चीजों को इधर-उधर कर रहा हूं। जब तक यह ठीक नहीं हो जाता, तब तक आप इसे आर्काइव.ऑर्ग
ब्रायन डेनी

1
मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन मुझे अभी एक समस्या सामने आई है, जिसे हल कर सकते हैं, हालांकि इस वर्ग को किसी भी तरह घोषणा पत्र में घोषित करने की आवश्यकता है, नहीं? मैं कक्षा को इस तरह महसूस नहीं कर सकता कि मुझे क्या याद आ रहा है ...
जीव किस्टेन

1
@ZivKesten नाम = विशेषता के बारे में कैसे प्रकट करने के लिए आवेदन टैग के लिए?
माइक जूल

@mgc आप अपने समय हो गया धन्यवाद, और हां में है कि कैसे मैं अंत में यह काम किया, यह भी मैं उस वर्ग के उदाहरणों बनाया जहाँ भी मैं इसे इस वर्ग के लिए एक कलाकारों के साथ getApplicationContext () देकर जरूरत
जीव Kesten

57

Applicationमिसाल के तौर पर गिनने वाले गलत हैं। सबसे पहले, ऐसा लग सकता है कि जब तक Applicationमौजूद है जब तक पूरी ऐप प्रक्रिया मौजूद है लेकिन यह एक गलत धारणा है।

ओएस आवश्यकतानुसार प्रक्रियाओं को मार सकता है। सभी प्रक्रियाओं को डॉक्टर में निर्दिष्ट "हत्या" के 5 स्तरों में विभाजित किया गया है ।

उदाहरण के लिए, यदि आपका ऐप इनकमिंग कॉल का उत्तर देने वाले उपयोगकर्ता के कारण बैकग्राउंड में चला जाता है, तो रैम की स्थिति के आधार पर, ओएस आपकी प्रक्रिया को मार सकता है (या नहीं भी सकता है) प्रक्रिया में Applicationउदाहरण को नष्ट कर सकता है। ।

मुझे लगता है कि आपके डेटा को आंतरिक संग्रहण फ़ाइल में बनाए रखने के लिए एक बेहतर दृष्टिकोण होगा और तब इसे पढ़ें जब आपकी गतिविधि फिर से शुरू हो।

अपडेट करें:

मुझे कई नकारात्मक प्रतिक्रियाएं मिलीं, इसलिए यह एक स्पष्टीकरण जोड़ने का समय है। :) ठीक है, शुरू में मैंने एक गलत धारणा का इस्तेमाल किया कि राज्य वास्तव में ऐप के लिए महत्वपूर्ण है। हालांकि अगर आपका ऐप ठीक है कि कभी-कभी राज्य खो जाता है (यह कुछ छवियां हो सकती हैं, जो कि बस फिर से रीडेड / रिडाउक्ड हो जाएंगी), तो इसे सदस्य के रूप में रखना पूरी तरह से ठीक है Application


14
यदि एप्लिकेशन मारा जाता है, तो कौन परवाह करता है, है ना? आवेदन दूर हो गया है। जैसा कि मैं इसे समझता हूं, एंड्रॉइड उन प्रक्रियाओं को पुनः प्राप्त करेगा जिसमें मेमोरी जैसी गतिविधियां शामिल हैं। यदि एप्लिकेशन युक्त प्रक्रिया को मार दिया जाता है (यदि एंड्रॉइड भी ऐसा करेगा?), तो यह अनिवार्य रूप से ऐप को मारने जैसा है। उपयोगकर्ता को फिर से ऐप लॉन्च करने की आवश्यकता होगी और उस बिंदु पर, कौन परवाह करता है? यह एप्लिकेशन का एक नया उदाहरण है।
एंड्रयू

14
यह उत्पादन में हमारे लिए एक अचंभित करने वाला आश्चर्य था। मेरा विश्वास करो कि एंड्रॉइड प्रक्रियाओं को मारता है, यह सिर्फ रैम राज्य और प्रलेखन में वर्णित अन्य कारकों पर निर्भर करता है। यह हमारे लिए एक बुरा सपना था इसलिए मैं सिर्फ अपना असली अनुभव साझा करता हूं। वैसे हमारे पास एमुलेटर पर यह नहीं था, लेकिन वास्तविक दुनिया में कुछ डिवाइस ऐप के साथ 'अतिभारित' हैं, इसलिए एक पृष्ठभूमि प्रक्रिया को मारना एक सामान्य स्थिति है। हां, यदि उपयोगकर्ता फिर ऐप को अग्रभूमि में लाने का निर्णय लेता है - ओएस Applicationउदाहरण सहित अपने स्टैक को पुनर्स्थापित करता है , हालांकि तब तक आपका स्थैतिक डेटा नहीं होगा जब तक आप इसे जारी नहीं रखते।
विट खूदेंको

2
मुझे लगता है कि मैं शायद एक हाइब्रिड दृष्टिकोण का उपयोग करने जा रहा हूं। मैं पहले से ही अभिविन्यास परिवर्तन (जिसमें अन्य लाभ हैं) को ओवरराइड करने के लिए प्रकट चाल के बारे में जानता था। चूंकि आवेदन एक खेल है, मुझे यकीन नहीं है कि लॉन्च के बीच डेटा को जारी रखना पर्याप्त "महत्वपूर्ण" है; हालांकि यह संभवतः बहुत कठिन नहीं होगा क्योंकि अधिकांश डेटा को क्रमबद्ध किया जा सकता है (हालांकि मैं हर अभिविन्यास परिवर्तन के बीच क्रमबद्ध और अनसुना नहीं करना चाहूंगा)। मैं निश्चित रूप से इनपुट की सराहना करता हूं। मैं यह नहीं कहूंगा कि ऐप इंस्टा पर निर्भर रहने वाले लोग "गलत" हैं। बहुत कुछ ऐप पर निर्भर करता है :)।
डेव

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

2
मेरे पास जटिल संरचना के साथ लगभग 1mb डेटा है। जब डिवाइस काम के साथ ओवरलोड हो जाता है तो सीरियलाइज़ / डिसेरियलाइज़ मुझे 2-3 सेकंड तक खर्च कर सकता है। गतिविधियों के बीच बचाने / लोड करने का आइडिया बहुत अधिक समय खर्च करता है। मैं एप्लिकेशन को स्टोरेज के रूप में उपयोग करता हूं। निश्चित रूप से मेरे डेटा वर्ग को एप्लिकेशन इंस्टेंस में संग्रहीत किया गया है, जो हर मेट्रो पर चेक करता है - डेटा अभी भी जीवित है या लोड किया जाना है। इसलिए डेव को यह करना होगा: 1. आवेदन में लोड / बचत वित्त प्रदान करें। 3. डेटा की जाँच के लिए ट्रिपल चेक लॉजिक।
कोस्टाडिन

6

यदि आप किसी गतिविधि के बाहर "ग्लोबल सिंगलटन" को एक्सेस करना चाहते हैं और आप Contextसिंगलटन को प्राप्त करने के लिए सभी सम्मिलित वस्तुओं से नहीं गुजरना चाहते हैं , तो आप केवल अपने एप्लिकेशन क्लास में एक स्थिर विशेषता को परिभाषित कर सकते हैं, जो संदर्भ को रखती है। अपने आप। बस onCreate()विधि में विशेषता इनिशियलाइज़ करें ।

उदाहरण के लिए:

public class ApplicationController extends Application {
    private static ApplicationController _appCtrl;

    public static ApplicationController getAppCtrl()
    {
         return _appCtrl;
    }
}

क्योंकि उप-वर्ग Applicationभी संसाधन प्राप्त कर सकते हैं, आप एक स्थैतिक विधि को परिभाषित करने पर उन्हें आसानी से एक्सेस कर सकते हैं, जो उन्हें लौटाता है, जैसे:

public static Resources getAppResources()
{
    return _appCtrl.getResources();
}

लेकिन मेमोरी लीक से बचने के लिए कॉनटेक्स्ट के संदर्भ में गुजरते समय बहुत सावधान रहें ।


6
आप यह ध्यान रखना भूल गए कि आपको android: name = "जोड़ना होगा। ApplicationController" xml को तुरंत प्रदर्शित करने के लिए आपके प्रकट होने में एप्लिकेशन टैग को विशेषता है।
एगिए 5

आपको वास्तव में ऐसा करने के लिए विस्तार Applicationकरने की आवश्यकता नहीं है । आप ऐसा करने के लिए किसी भी वर्ग में एक स्थिर सदस्य चर घोषित कर सकते हैं ।
डेविड वासर

2

डेव, यह किस तरह का डेटा है? यदि यह सामान्य डेटा है जो अनुप्रयोग से संबंधित है (उदाहरण: उपयोगकर्ता डेटा), तो अनुप्रयोग वर्ग का विस्तार करें और इसे वहां संग्रहीत करें। यदि डेटा गतिविधि से संबंधित है, तो आपको स्क्रीन रोटेशन पर डेटा को बनाए रखने के लिए onSaveInstanceState और onRestoreInstanceState हैंडलर का उपयोग करना चाहिए।


क्या होगा अगर डेटा पार्सल में स्टोर करने के लिए वास्तव में बड़ा है? यह वही है जो प्राप्त कर रहा है: android.os.TransactionTooLargeException: डेटा पार्सल आकार 838396 बाइट्स
अर्जुन इस्सर

1

आप वास्तव में अभिविन्यास कार्यक्षमता को ओवरराइड कर सकते हैं ताकि यह सुनिश्चित हो सके कि आपकी गतिविधि नष्ट नहीं हुई है और फिर से बनाई गई है। यहाँ देखो ।


16
आप बहुत सारी चीजें कर सकते हैं। इसका मतलब यह नहीं है कि वे अच्छे विचार हैं। यह एक अच्छा विचार नहीं है।
एंड्रयू

स्क्रीन ओरिएंटेशन को बदलकर परीक्षण करना सबसे आसान तरीका है, यह सुनिश्चित करने के लिए कि आपका ऐप एंड्रॉइड यह करने के लिए क्या करता है।
18446744073709551615

0

आप अनुप्रयोग वर्ग बना सकते हैं और अपने सभी डेटा को अपने आवेदन में कहीं भी उपयोग करने के लिए उस कालस पर सहेज सकते हैं।


0

मुझे पता है कि यह बहुत पुराना सवाल है, लेकिन जेटपैक घटकों से व्यूमॉडल का उपयोग गतिविधि रोटेशन के बीच डेटा को संरक्षित करने का सबसे अच्छा तरीका है।

ViewModel वर्ग को जीवन चक्र में सचेत तरीके से UI से संबंधित डेटा को संग्रहीत और प्रबंधित करने के लिए डिज़ाइन किया गया है। ViewModel वर्ग डेटा को स्क्रीन घुमाव जैसे कॉन्फ़िगरेशन परिवर्तन से बचने की अनुमति देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.