2012-12-15 38 views
8

मैं एक एंड्रॉइड ऐप बना रहा हूं जहां प्रत्येक इकाई में एक बिटमैप होता है जो इसके स्प्राइट का प्रतिनिधित्व करता है। हालांकि, प्रत्येक इकाई को डुप्लिकेट किया जा सकता है (उदाहरण के लिए इकाई asdf की 3 प्रतियां हो सकती हैं)।कमजोर हैमपैप मूल्यों के कमजोर संदर्भ के साथ?

एक दृष्टिकोण सभी sprites को पहले लोड करना है, और फिर इकाइयों के रचनाकारों में सही स्प्राइट डालना है।

हालांकि, मैं बिटमैप्स को आलसी रूप से डीकोड करना चाहता हूं, ताकि इकाइयों के निर्माता बिटमैप्स को डीकोड कर सकें। इसके साथ एकमात्र समस्या यह है कि डुप्लीकेट इकाइयां 2x स्मृति का उपयोग करके दो बार समान बिटमैप लोड करेंगी (या एन बार अगर इकाई एन बार बनाई जाती है)।

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

हैशप को कमजोर संदर्भित मानों के साथ स्विच करने का सबसे अच्छा तरीका क्या है? दूसरे शब्दों में, मैं एक संरचना चाहता हूं जहां मूल्य किसी अन्य ऑब्जेक्ट का संदर्भ नहीं रखता है, लेकिन जब तक कोई अन्य ऑब्जेक्ट इसे संदर्भित नहीं करता है, तो यह GC'd हो सकता है।

उत्तर

11

आपने जो कुछ कहा है, उसमें बहुत कुछ - बिटमैप (मानचित्र का ऑब्जेक्ट पक्ष) बिटमैप के बजाए एक वीक रेफरेंस बनाएं। फिर आपको यह देखने के लिए एक अतिरिक्त जांच जोड़नी है कि संदर्भ अभी भी आपकी संस्थाओं को पास करने से पहले मान्य है या नहीं। यहां सामान्य विचार का एक त्वरित स्केच है।

public class SingularBitmapFactory { 
    private HashMap <String, WeakReference<Bitmap>> cache = new HashMap<String, WeakReference<Bitmap>>(); 

    public Bitmap getBitmap(String key) { 
     Bitmap image = null; 
     WeakReference<Bitmap> ref = cache.get(key); 
     if(ref != null) { 
      image = ref.get(); 
     } 
     if(image == null) { 
      // Load image here ... 
      cache.put(key, new WeakReference<Bitmap>(image)); 
     } 
     return image; 
    } 
} 
+0

आप से! यह बिटमैप से निपटने के मामले में बहुत सरल और बहुत प्रभावी है। केवल एक कुंजी के रूप में पूर्ण पथ का उपयोग करना और यह बहुत सुविधाजनक है और विवरण से लीक –

-3

सबसे अच्छा तरीका WeakHashMap क्लास का उपयोग करना है जो आपके लिए सभी काम करता है और आपके कोड में किसी भी बदलाव की आवश्यकता नहीं है। यहां वास्तव में एक अच्छा ट्यूटोरियल है: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references इसकी बजाय पुरानी लेकिन अभी भी ठीक है। यह महत्वपूर्ण है कि WeakHashMap कुंजी के लिए एक कमजोर संदर्भ संग्रहीत करता है। इसका मतलब है कि आप केवल एक स्थिर स्ट्रिंग मान का उपयोग कुंजी के रूप में नहीं कर सकते हैं बल्कि इसके बजाय इंटीजर की तरह कुछ उपयोग कर सकते हैं और इसे एक कमेंट क्लास में कमजोर संदर्भ के रूप में स्टोर कर सकते हैं।

+1

हम्म से छुटकारा पाने में मदद मिली है, WeakHashMap मूल्य के लिए कुंजी के कमजोर संदर्भों को प्रतीत होता है। –

+0

यह करता है। धन्यवाद। मैंने जवाब संपादित कर लिया है। – SIGKILL

+1

यह प्रश्न – siledh

7

पुराना सवाल है, लेकिन मैं यह आज की जरूरत है, और @ iagreen का जवाब मैं विचार सामान्यीकृत है उसके आधार पर, हो सकता है यह किसी के लिए काम में आता ...

public static class WeakValueHashMap<K,V> { 
    private HashMap<K,WeakReference<V>> mDatabase=new HashMap<K, WeakReference<V>>(); 
    public V get(K key) { 
     WeakReference<V> weakRef=mDatabase.get(key); 
     if (weakRef==null) return null; 
     V result=weakRef.get(); 
     if (result==null) { 
      // edge case where the key exists but the object has been garbage collected 
      // we remove the key from the table, because tables are slower the more 
      // keys they have (@kisp's comment) 
      mDatabase.remove(key); 
     } 
     return result; 
    } 
    public void put(K key, V value) { 
     mDatabase.put(key, new WeakReference<V>(value)); 
    } 
} 

तो आप बस उदाहरण के लिए कर सकते हैं

private WeakValueHashMap<String,Drawable> mTextDrawables=new WeakValueHashMap<String,Drawable>(); 

और ड्रॉएबल Weakreferences साथ संग्रहीत किया जाएगा।

विधि "containsValue" लागू करने के लिए जटिल हो सकता है, आप पुनरावृति करना होगा और सभी WeakRefs भिन्नता ...

+2

का उत्तर नहीं देता है यह बहुत अच्छा लगता है: मुझे लगता है कि आपको पुरानी कुंजी हटाने का ख्याल रखना चाहिए। थोड़ी देर के बाद बहुत सारी चाबियाँ लुकअप को धीमा कर देगी। (लोड फैक्टर उच्च होगा, बहुत सी जगह का उपभोग करेगा)। अगर आप भी कुंजी को नहीं हटाते हैं। सुझाव: कमजोर Ref == शून्य के मामले में प्राप्त विधि में mDatabase निकालें। चियर्स – kisp