2011-03-21 16 views
7

में वीएम बजट से अधिक है, मैं समझता हूं कि यह प्रश्न कुछ बार पूछा जाता है। समाधान में से कोई भी स्पष्ट नहीं है। मुझे समस्या की व्याख्या करने दो।एंड्रॉइड आउटफमेमरी त्रुटि बिटमैप आकार 2.3.3

  1. मेरे पास एक गतिविधि है जो एक समय में 4 छवियों को लोड करती है।
  2. मैं ऑनस्यूम() विधि में छवियों को लोड करता हूं।
  3. गतिविधि लोड होने पर बिटमैप त्रुटि फेंकता है।

नोट्स।

  1. मैं setImageResource (R.drawable.xxxx) विधि कॉल का उपयोग कर छवि सेट कर रहा हूं और सीधे बिटमैप/ड्रॉबल्स नहीं।
  2. छवियों को सही ढंग से स्केल किया गया है।
  3. सक्रियता काम 2.3 से पहले सभी अनुकरणकों में ठीक काम करती है और वास्तविक डिवाइस (सैमसंग गैलेक्सी 5)
  4. त्रुटि पहले प्रारंभिकरण पर दिखाई दे रही है और कोई अभिविन्यास परिवर्तन ईवेंट निकाल दिया गया है।
  5. छवियां 800 x 600 स्केल और आकार में 15kb (प्रत्येक) औसत हैं।

मुझे कोई समाधान बताएं। अगर आपको एंड्रॉइड 2.3.3 एमुलेटर के साथ समान समस्याएं हैं तो मुझे बताएं।

[अद्यतन] -snippets

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
      ... 
    img_topLeft = (ImageView) findViewById(R.id.Img_Alph_Q_TopLeft); 
    img_topRight = (ImageView) findViewById(R.id.Img_Alph_Q_TopRight); 
    img_bottomLeft = (ImageView) findViewById(R.id.Img_Alph_Q_BottomLeft); 
    img_bottomRight = (ImageView) findViewById(R.id.Img_Alph_Q_BottomRight); 
    ... 
    } 
protected void onResume() { 
    super.onResume(); 
      img_topLeft.setImageResource(R.drawable.xxx); 
      img_topRight.setImageResource(R.drawable.xxx); 
      img_bottomLeft.setImageResource(R.drawable.xxx); 
      img_bottomRight.setImageResource(R.drawable.xxx); 
    ... 
    } 

03-21 08:59:17.362: ERROR/dalvikvm-heap(5883): 4320000-byte external allocation too large for this process. 03-21 08:59:17.412: ERROR/GraphicsJNI(5883): VM won't let us allocate 4320000 bytes 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): FATAL EXCEPTION: main 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.nativeCreate(Native Method) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createBitmap(Bitmap.java:477) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createBitmap(Bitmap.java:444) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:349) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:498) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:473) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.content.res.Resources.loadDrawable(Resources.java:1709) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.content.res.Resources.getDrawable(Resources.java:581) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.widget.ImageView.resolveUri(ImageView.java:501) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.widget.ImageView.setImageResource(ImageView.java:280) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at Quiz.java:124) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): Quiz.onResume(Quiz.java:92) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.Activity.performResume(Activity.java:3832) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1668) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.os.Handler.dispatchMessage(Handler.java:99) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.os.Looper.loop(Looper.java:123) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.main(ActivityThread.java:3683) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at java.lang.reflect.Method.invokeNative(Native Method) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at java.lang.reflect.Method.invoke(Method.java:507) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at dalvik.system.NativeStart.main(Native Method)

धन्यवाद। इसे हल करने के लिए प्रबंधित। दूसरों के लाभ के लिए कोड साझा करना कस्टम क्लास जिसने इस समस्या का समाधान किया। @ जनार्दनन पर आधारित। लिंक।

public class BitmapResizer { 

public static Bitmap decodeImage(Resources res, int id ,int requiredSize){ 
    try { 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeResource(res, id, o); 

     //Find the correct scale value. It should be the power of 2. 
     final int REQUIRED_SIZE=requiredSize; 
     int width_tmp=o.outWidth, height_tmp=o.outHeight; 
     int scale=1; 
     while(true){ 
      if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
       break; 
      width_tmp/=2; 
      height_tmp/=2; 
      scale*=2; 
     } 

     //decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize=scale; 
     return BitmapFactory.decodeResource(res, id, o2); 
    } catch (Exception e) { 

    } 
    return null; 
} 

} 

//Class call 
int requiredsize = 100; // Still playing around with this number to find the optimum value 
img_topLeft.setImageBitmap(BitmapResizer.decodeImage(getResources(), 
     AlphResourceSet.R.drawable.xxx, requiredsize)); 
+0

पोस्ट अपने onResume कोड आकार बदलने के लिए इस स्निपेट का उपयोग कर सकते हैं, और यह मदद करने के लिए आसान हो सकता है। –

उत्तर

3

बिटमैप बहुत मेमोरी स्पेस का उपभोग करता है। गतिविधि पर लोड की गई सभी छवियों के लिए एक नया बिटमैप वैरिएबल न बनाएं, इसके बजाय आप एक बिटमैप वैरिएबल बना सकते हैं और जितना संभव हो उतना पुन: उपयोग कर सकते हैं।

आप बिटमैप

http://pastebin.com/D8vbQd2u

+0

क्या मुझे इस पर विचार करने की आवश्यकता है कि मैं बिटमैप वैरिएबल का उपयोग नहीं कर रहा हूं? मैं प्रत्यक्ष रूप से संदर्भित संदर्भ फ़ॉर्म का उपयोग करता हूं। कोड संलग्न – GSree

+0

आपको छोटी छवियों के आकार बदलने पर विचार करने की आवश्यकता नहीं है, लेकिन एक गतिविधि पर 64 केबी यूआई को तनाव देगा और स्मृति का उपभोग करेगा। उन्हें बिटमैप में परिवर्तित करें और उन्हें छविदृश्य – Jana

+0

rdhanan पर फ़ीड करें। 64kb क्या है? प्रति गतिविधि एक छवि आकार है। मेरी छवियां ~ 15kb आकार में पीएनजी प्रारूप में हैं। एक गतिविधि में 4 छवियां होंगी। तो ~ 15 x 4 = ~ 60 केबी। – GSree

0

आप गतिविधि + स्टैकट्रेस का एक कोड स्निपेट पोस्ट कर सकते हैं।

क्या आप पहले से ही Avoiding memory leaks article देख चुके हैं?

विशेष रूप से निम्नलिखित हिस्सा:

एक Drawable एक दृश्य से जुड़ा हुआ है जब, देखने drawable पर एक कॉलबैक के रूप में स्थापित किया जाएगा। उपरोक्त कोड स्निपेट में, इसका मतलब है कि ड्रॉबल में टेक्स्टव्यू का संदर्भ है, जिसमें स्वयं गतिविधि (संदर्भ) के संदर्भ में है, जो बदले में बहुत कुछ (आपके कोड के आधार पर) के संदर्भ में है।

+0

मैंने लिंक की जांच की। यकीन नहीं है कि मेरे कोड के साथ मैं बहुत कुछ कर सकता हूं। कोड स्निपेट को प्रश्न में अपडेट किया गया। अगर मुझे इस पर आधारित कुछ संशोधन करने की ज़रूरत है तो कृपया जांचें और मुझे बताएं। – GSree

0

यह प्रतीत होता है कि छवियां प्रकृति में बहुत भारी हैं। मैं AsyncTimer को शुरू करने की अनुशंसा करता हूं जो वास्तव में बिटमैप आवृत्ति देता है और AsyncTask के doBackground() में छवि आईडी पास करता है और बिटमैप क्लास के createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) विधि का उपयोग करके 32 x 32 कहने के आकार को पुन: सहेजता है।

+0

छवियां 800 x 600 स्केल और औसत 15kb (प्रत्येक) आकार में हैं। क्या आप AsyncTimer को कैसे करें पर कुछ स्निपेट पोस्ट कर सकते हैं? – GSree

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