2012-04-21 17 views
41

मुझे पता है कि एंड्रॉइड पर स्थिर चर का उपयोग काफी जोखिम भरा है, खासकर यदि आप उन्हें गतिविधियों के संदर्भ में देखते हैं। हालांकि, अगर मेरे पास एक वर्ग है जो आवेदन बढ़ाता है (चलो इस वर्ग को "ऐप" कहते हैं), क्या यह इस वर्ग के उदाहरण के संदर्भ में सुरक्षित है?क्या ऐप संदर्भ को एंड्रॉइड में एक स्थिर चर में सहेजना सुरक्षित है?

यदि हां, तो यह भी सुरक्षित किसी अन्य वर्ग आवेदन संदर्भ के संदर्भ में किसी भी तरह का है करने के लिए के लिए है? मेरा मतलब है, अगर मेरे पास किसी भी प्रकार की कक्षा में एप्लिकेशन संदर्भ का संदर्भ है तो क्या स्मृति मेमोरी हो सकती है?

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

इसके अलावा, नहीं है कि यह ज्यादा मायने रखती है, लेकिन अगर मैं कई प्रक्रियाओं का उपयोग करें, मैं हर प्रक्रिया पर App वर्ग के लिए पूरी तरह से अलग संदर्भ मिलेगा?

कोड का एक उदाहरण के रूप में, यहाँ है कि मैं क्या के बारे में सोच रहा हूँ:

public class App extends Application 
{ 
    private static Context _appContext; 

    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
     _appContext = this; 
    } 

    public static Context getAppContext() 
    { 
     return _appContext; 
    } 
} 
+0

डुप्लिकेट? https://stackoverflow.com/questions/2002288/static-way-to-get-context-on-android –

+1

@YoushaAleayoub सं। प्रश्न यह है कि यह सुरक्षित है। यदि यह संभव नहीं है और यह कैसे करें। मैंने पहले ही दिखाया है कि यह कैसे करें। –

उत्तर

27

तो वह एक स्थिर चर करने के लिए एप्लिकेशन संदर्भ बचाने के लिए सुरक्षित है?

वर्तमान में, हाँ, यह प्रकट होता है यह सुरक्षित है, हालांकि मैं getAppContext() वापसी Context नहीं होगा, लेकिन इसके बजाय App या Application लौट आते हैं।

कहा जा रहा है कि तथ्य यह है कि कोर एंड्रॉइड टीम ने इसे पहली बार स्थापित नहीं किया है, यह बताता है कि शायद ऐसे छिपे हुए मुद्दे हो सकते हैं जिनके बारे में हम अनजान हैं, या भविष्य में यह दृष्टिकोण समस्याएं पेश कर सकता है ।

कहावत का परिवर्णी शब्द चला जाता है के रूप में, YMMV। :-)


संपादित

यदि हां, तो यह भी सुरक्षित किसी अन्य वर्ग आवेदन संदर्भ के संदर्भ में किसी भी तरह का है करने के लिए के लिए है?

मुझे नहीं पता कि आपका "सुरक्षित" यहां क्या मतलब है।

लेकिन यदि मैं एकाधिक प्रक्रियाओं का उपयोग करता हूं, तो मुझे प्रत्येक प्रक्रिया पर ऐप क्लास के बिल्कुल अलग संदर्भ मिलेंगे, है ना?

आप कई प्रक्रियाओं का उपयोग करते हैं, तो आप एक ट्राउट के साथ थप्पड़ मारा जाना चाहिए। लेकिन, हाँ, आपको प्रति प्रक्रिया अलग App उदाहरण प्राप्त करना चाहिए।

+0

तो, क्या आप किसी भी तरह से सोच सकते हैं कि संभावित समस्याओं का ख्याल रखेगा? क्या मुझे हार्ड संदर्भ के बजाय वीक रेफरेंस का उपयोग करना चाहिए? भी, कृपया बाकी सवालों के जवाब देने का प्रयास करें। –

+1

@androiddeveloper: "क्या आप किसी भी तरह से सोच सकते हैं कि संभावित समस्याओं का ख्याल रखेगा?" - चूंकि हम नहीं जानते कि संभावित समस्याएं क्या हैं, उनके लिए समाधान तैयार करना असंभव है। – CommonsWare

+0

मैंने कुछ समय पहले आपके दृष्टिकोण के बारे में भी सोचा था, क्योंकि हर बार संदर्भ पारित करने में सहज नहीं है ... मुझे लगता है कि आप इस स्थिर चर को अपनी मुख्य गतिविधि से शुरू करते हैं, है ना? – Caumons

7

यह सुरक्षित होना चाहिए। इसके अलावा API docs से निम्नलिखित नोट आप के लिए प्रासंगिक हो सकता है:

सामान्य रूप से Application उपवर्ग की कोई जरूरत नहीं है। सबसे स्थिति में, स्थिर एकमात्र एक और मॉड्यूलर रास्ते में ही कार्यक्षमता प्रदान कर सकते हैं।यदि आपके सिंगलटन को वैश्विक संदर्भ की आवश्यकता है (उदाहरण के लिए प्रसारण रिसीवर पंजीकृत करने के लिए), इसे पुनर्प्राप्त करने के लिए फ़ंक्शन को संदर्भ दिया जा सकता है जो आंतरिक रूप से Context.getApplicationContext() का उपयोग करता है जब पहले सिंगलटन का निर्माण करता है।

+0

हां। क्या यह सच है कि स्थैतिक चर एंड्रॉइड में अजीब काम करते हैं? उदाहरण के लिए, यदि ऐप बहुत अधिक मेमोरी का उपयोग करता है, तो कुछ कक्षाएं अनलोड हो जाएंगी, इसलिए यदि उनमें स्थैतिक चर शामिल हैं, तो वे भी चले जाएंगे? –

+0

@Nate, कृपया किसी भी Google वेबसाइट पर कुछ संदर्भ दें जो कहता है कि यह इस तरह से काम करता है।कुछ डेवलपर्स का दावा है कि यह इस तरह से काम करता है और कुछ कहते हैं कि यह नहीं है (उपयोगकर्ता कॉमन्सवेयर की तरह)। तो यह एक बहुत भ्रमित विषय है। –

+0

@androiddeveloper, मुझे यह वेबसाइट से नहीं मिला। मुझे वास्तविक उपकरणों पर परीक्षण करके जानकारी मिली, जो किसी भी दस्तावेज से अधिक मजबूत संदर्भ है। इस तरह के व्यवहार को पुन: उत्पन्न करने का नमूना यहां दिया गया है। एक उपकरण प्राप्त करें जो आपको मैन्युअल रूप से स्मृति को साफ़ करने की अनुमति देता है। उदाहरण के लिए "जाओ टास्कमेनगर EX"। अपना ऐप चलाएं होम बटन दबाएं। स्वच्छ मेमोरी डीबगर में अपने ऐप पर लौटें। डीबगर में स्थिर चर का निरीक्षण करें। बीटीडब्ल्यू, मैंने इसे गो टास्कमेनर चलाने के बिना डिवाइस पर देखा है। यह सिर्फ इतना है कि यदि आप दोहराने योग्य कुछ देखना चाहते हैं, तो तुरंत, आपको स्मृति को स्वयं साफ़ करने की आवश्यकता है। – Nate

2

Application#onCreate() में ऐसा करना सुरक्षित है क्योंकि Application किसी भी गतिविधि से पहले बनाया गया है। यदि पृष्ठभूमि में आपका ऐप मारा जाता है, तो Application इंस्टेंस फिर से बनाया जाएगा और आपकी वैश्विक गतिविधि किसी भी गतिविधि चलाने से पहले सेट की जाएगी।

यह ध्यान रखना महत्वपूर्ण है कि आपको कभी भी गतिविधि से वैश्विक चर सेट नहीं करना चाहिए। यदि आप करते हैं, अपने अनुप्रयोग निम्नलिखित रास्ते में विफल हो सकता है:

  1. गतिविधि में वैश्विक सेट एक
  2. नेविगेट गतिविधि बी को
  3. अनुप्रयोग पृष्ठभूमि में चला जाता है
  4. फ्रेमवर्क अनुप्रयोग और प्रक्रिया
  5. एप्लिकेशन को मारता है बहाल किया गया है
  6. फ्रेमवर्क गतिविधि बी बनाता है। बैकस्टैक में गतिविधियां तब तक नहीं बनाई जाती जब तक आप उन्हें वापस नेविगेट नहीं करते हैं, इसलिए वैश्विक सेट नहीं है!
  7. गतिविधि बी वैश्विक उपयोग करने के लिए प्रयास करता है, और उछाल ... NullPointerException
1

दिलचस्प टिप्पणी स्टूडियो से ऊपर पॉप जब मैं बुरा स्थिर संदर्भों को साफ़ कर रही थी:

"यह एक रिसाव है (और भी तत्काल रन तोड़ता है)। "

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