2013-08-23 13 views
7

मैं एंड्रॉइड लेआउट में पृष्ठभूमि छवि देने के लिए android:background का उपयोग कर रहा हूं।
बड़ी पृष्ठभूमि छवि लोड करते समय OutOfMemory

08-24 00:40:19.237: E/dalvikvm-heap(8533): Out of memory on a 36000016-byte allocation. 


मैं एंड्रॉयड पर पृष्ठभूमि के रूप में बड़ी छवियों का उपयोग कैसे कर सकते हैं:
कुछ छवियों डाल करने के बाद मैं इस अपवाद मिल सकता है?
क्या मैं एप्लिकेशन हीप मेमोरी का विस्तार कर सकता हूं? या यह कुछ अच्छा नहीं है?

+3

जैसा कि इन सवालों में से कई में उल्लेख किया गया है, विशाल छवियों का उपयोग न करें (> अपने मामले में 30 एमबी) पृष्ठभूमि छवियों का उपयोग न करें। – kabuko

+2

स्टैक ओवरफ्लो में इस तरह के कई समान प्रश्न हैं। मैंने इसे हल करने के कई विकल्पों का सारांश बनाने की कोशिश की है: http://stackoverflow.com/questions/11820266/android-bitmapfactory-decodestream-out-of-memory-with-a-400kb-file-with-2mb- एफ/16528487 # 16528487 –

+0

एक बहुत बड़ी छवि का उपयोग न करने के अलावा, उपकरणों की क्षमता पर विचार करना चाहिए, असली समस्या यह है कि डिवाइस में पृष्ठभूमि की तरह चार्ज करने की क्षमता नहीं है। –

उत्तर

7

कृपया मेरे संबंधित सवाल पर एक नजर है: को छोटे से छोटा पृष्ठभूमि छवि रख कर अपने आवेदन की स्मृति के उपयोग को कम करने के

High resolution Image - OutOfMemoryError

प्रयास करें।

  • एप्लिकेशन में इसका उपयोग करने
  • नीचे का उपयोग पहले भी चित्र को काटने में इतना है कि यह स्क्रीन फिट बैठता है
  • छवि आगे सेक (जैसे फ़ोटोशॉप का उपयोग करें):

    इस के माध्यम से किया जा सकता है विधि जैसे ही आप कोई loger इसकी आवश्यकता के रूप में

  • सुनिश्चित करें कि आप स्मृति
  • में यह के कई उदाहरण नहीं रखते बनाने के अपने बिटमैप लोड करने के लिए
  • बिटमैप रीसायकल 10
  • बिटमैप

सुनिश्चित करें कि आप एक पृष्ठभूमि के रूप में सेट छवियों सही ढंग से लोड कर रहे हैं उपयोग करने के बाद अशक्त करने के लिए संदर्भ सेट (जैसे आकार में फसल, उदाहरण के लिए स्क्रीन आकार फिट) और स्मृति की आवश्यकता के साथ ही उन्हें अब आवश्यक नहीं है।

सुनिश्चित करें कि आपके पास स्मृति में आपके बिटमैप का केवल एक उदाहरण है। इसे प्रदर्शित करने के बाद, recycle() पर कॉल करें और अपना संदर्भ शून्य पर सेट करें। कोड के इस खूबसूरत टुकड़े के लिए Adam Stelmaszczyk को

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
     int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeResource(res, resId, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeResource(res, resId, options); 
} 

public static int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     // Calculate ratios of height and width to requested height and width 
     final int heightRatio = Math.round((float) height/(float) reqHeight); 
     final int widthRatio = Math.round((float) width/(float) reqWidth); 

     // Choose the smallest ratio as inSampleSize value, this will guarantee 
     // a final image with both dimensions larger than or equal to the 
     // requested height and width. 
     inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
    } 

    return inSampleSize; 
} 

धन्यवाद:

इस तरह आप अपने छवियों को लोड कर सकता है।

+0

अरे, बिटमैप का उपयोग करने के बाद शून्य के संदर्भ को सेट करके आपका क्या मतलब है? –

5

मुझे लेआउट में पृष्ठभूमि छवियों के कारण एक समान समस्या का अनुभव हुआ है। किसी छवि के स्मृति आवंटन का सामान्य आकार ऊंचाई * चौड़ाई * 4 बाइट्स (मोड ARGB_8888, डिफ़ॉल्ट मोड में) होना चाहिए।

यदि आप गतिविधि दिखाते समय 30 एमबी देखते हैं और आवंटन करते हैं तो कुछ समस्या होनी चाहिए। जांचें कि क्या आप अपनी पृष्ठभूमि छवियों को खींचने योग्य फ़ोल्डर में रख रहे हैं। उस स्थिति में, सिस्टम को उस छवि को स्क्रीन के विशिष्ट घनत्व पर स्केल करना चाहिए, जिससे बड़ी मेमोरी ओवरहेड हो जाती है।

समाधान:

  1. प्लेस प्रत्येक drawable फ़ोल्डर में पृष्ठभूमि छवि के विशेष संस्करण (mdpi, HDPI, XHDPI ...)।
  2. "चित्रकारी-नोडपी" नामक एक विशेष संसाधन फ़ोल्डर में पृष्ठभूमि छवि रखें।सिस्टम इस निर्देशिका में रखी गई छवियों को स्केल करने की कोशिश नहीं करेगा, इसलिए केवल एक छिद्रण प्रक्रिया की जाती है और आवंटित स्मृति की अपेक्षा की जाएगी। इस answer

    आशा इस मदद करता है में

में अधिक जानकारी।

+0

यह आधे में मेरे ग्राफिक्स मेमोरी आवंटन में कटौती! धन्यवाद! – Magritte

1

can I expand the application heap memory?

हाँ, आप कर सकते हैं। अपने Manifest.xml में बस android:largeHeap:="true" सेट करें।

<application 
     android:name="com.pepperonas.libredrive.App" 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:largeHeap="true" 
     android:label="@string/app_name" 
     android:launchMode="standard"> 
+0

यह काम नहीं करता है, ऐप्स अभी भी स्मृति से बाहर हो सकते हैं, और बड़े ऐप के साथ, अपने ऐप को भी धीमा कर सकते हैं। https://developer.android.com/training/articles/memory.html इसके अतिरिक्त, बड़े ढेर आकार सभी उपकरणों पर समान नहीं हैं और, जब सीमित RAM वाले डिवाइस पर चलते हैं, तो बड़े ढेर का आकार बिल्कुल सही हो सकता है नियमित ढेर आकार के समान। इसलिए यदि आप बड़े ढेर आकार का अनुरोध करते हैं, तो आपको नियमित हेप आकार की जांच करने के लिए getMemoryClass() पर कॉल करना चाहिए और हमेशा उस सीमा से नीचे रहने का प्रयास करना चाहिए। – Nickmccomb

+0

मेरे लिए इस सुविधा को सेट करने के लिए एक नक्शा खंड (जो 30k भू-मार्कर तक दिखाता है) में एक समस्या हल हो गई है ... और हाँ, यह स्पष्ट है कि प्रत्येक डिवाइस में सीमित रैम है - इसलिए हमें सबसे कम संसाधनों का उपभोग करने वाले कोड का उत्पादन करना चाहिए (कभी-कभी डेटा को कैश करने के लिए बेहतर होता है, कभी-कभी सीपीयू का उपयोग करने के लिए यह अधिक अनुशंसित होता है)। इस बिंदु पर कोई भी संक्षिप्त जवाब नहीं दे सकता है। लेकिन जैसा कि मैंने कहा, उपरोक्त इस स्निपेट ने कुछ परिस्थितियों में मेरे लिए चाल की है .. इसलिए यह कहना गलत है कि "यह काम नहीं करता है"। –

+0

मैं सहमत नहीं हूं। मेरा मानना ​​है कि एक समाधान को आपके ऐप को धीमा नहीं करना चाहिए और सड़क के नीचे और समस्याएं पेश नहीं करनी चाहिए। ऐप काम नहीं कर रहा है क्योंकि यह बिटमैप्स का खराब उपयोग कर रहा है, जिससे मेमोरी त्रुटि समाप्त हो गई है। आपका "समाधान" इसे ठीक नहीं करेगा क्योंकि, यदि बिटमैप आपके फ़िक्स के साथ उपलब्ध मेमोरी के आकार के नीचे है (जो यह नहीं हो सकता है), एक बार और बिटमैप्स पेश किए जाने पर यह निश्चित रूप से होगा, और ओओएम त्रुटि अभी भी होगी । यह एक समाधान नहीं है। – Nickmccomb

3

मैं एक ही समस्या थी और पालन करते हुए इसे तय:

  1. एक drawable-nodpi फ़ोल्डर बनाएँ और वहाँ में अपनी पृष्ठभूमि छवियों को डाल दिया।

  2. छवियों http://square.github.io/picasso/

फ़िट() और .centerCrop() और पिकासो के साथ उन्हें प्रदर्शित करें प्रदर्शित करने के लिए उपयोग पिकासो छवि मापता है अगर यह

ImageView ivLogo = (ImageView) findViewById(R.id.ivLogo); 
Picasso.with(getApplicationContext()) 
    .load(R.drawable.logo) 
    .fit() 
    .centerCrop() 
    .into(ivLogo); 

यदि आप करते हैं की जरूरत है किसी भी तरह से स्मृति से बाहर निकलें, पिकासो आपको ओओएम त्रुटि देने के बजाय छवि को प्रदर्शित नहीं करेगा। आशा है कि ये आपकी मदद करेगा!

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