2011-04-02 9 views
12

मेरे पास कैनवास पर बिटमैप टाइल्स ड्राइंग करके लागू एक कस्टम ऑफ़लाइन मानचित्र है। मैं जीसी रन को कम करने के लिए ऑब्जेक्ट क्रिएशन को खत्म करने की कोशिश कर रहा हूं और इसलिए नक्शा स्क्रॉलिंग को आसान बना देता हूं। मैं आवंटन ट्रैकर में देखता हूं कि BitmapFactory.decodeFile (...) हमेशा बाइट [16400] ऑब्जेक्ट बनाता है। मैंने सोचा था कि BitmapFactory.Options की inTempStorage क्षेत्र की स्थापना है कि बदल जाएगा:BitmapFactory.Options.inTempStorage फ़ील्ड

byte[] buffer = new byte[16*1024]; 
// ... 
BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inPreferredConfig = Config.RGB_565; 
options.inTempStorage = buffer; 
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options); 

लेकिन फिर भी इस कोड के साथ मैं अब भी decodeFile बाइट [] सरणी बनाने देखें। तो समस्या क्या है?

उत्तर

16

संक्षेप में, समस्या यह है कि जब आप BitmapFactory.decodeFile(String, Options) का उपयोग करते हैं तो एंड्रॉइड options.inTempStorage से स्वतंत्र रूप से 16 केबी BufferedInputStream आवंटित करेगा।

अधिक विस्तृत होने के लिए: BitmapFactory.decodeFile(String, Options)BitmapFactory.decodeStream(InputStream, Rect, Options) के आसपास एक रैपर है जो FileInputStream का उपयोग करता है। BitmapFactory.decodeStream(InputStream, Rect, Options) के कार्यान्वयन में, वहाँ this code है:

public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) { 
    // ... 

    // we need mark/reset to work properly 
    if (!is.markSupported()) { 
     is = new BufferedInputStream(is, 16 * 1024); 
    } 

    // ... 
} 

के बाद से FileInputStream के markSupported() रिटर्न false, इसका मतलब है कि options.inTempStorage की स्वतंत्र रूप से, एक 16 kB बफर के साथ एक BufferedInputStream अगर आप BitmapFactory.decodeFile(String, Options) का उपयोग आप के लिए बनाया जाएगा।

इस 16 kB आवंटन से बचने के लिए, आप एक InputStream जिसके लिए markSupported() रिटर्न true के साथ सीधे BitmapFactory.decodeStream(InputStream, Rect, Options) उपयोग करने का प्रयास कर सकता है।

मैं दो विकल्प है कि में देख लायक हो सकता है के बारे में सोच सकते हैं:

  1. एक छोटे बफर
  2. उपयोग AssetManager.AssetInputStream रूप AssetManager.open(...) द्वारा दिया के साथ अपने स्वयं BufferedInputStream का उपयोग करें (यह कैसे उपयोग करने पर मेरा उत्तर here देखना)। इसका markSupported()true देता है।

पहला विकल्प अधिक मदद नहीं कर सकता है, आपके पास अभी भी एक बाइट [] सरणी आवंटित होगी, लेकिन कम से कम यह आपके नियंत्रण में है। दूसरा विकल्प सबसे उपयोगी साबित हो सकता है, यदि आपकी परिस्थितियां आपको इस दृष्टिकोण का उपयोग करने की अनुमति देती हैं।

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