2016-08-24 39 views
-1

我嘗試使用獲取OutOfMemory異常的位圖加載我的UI。我以前使用過PNG,然後將它們轉換爲GIF,希望通過加載位圖來減少內存使用量。圖像總數爲291kb(使用PNG時約爲2.2mb)。通過位圖加載UI時發生OutOfMemory異常

我使用使用inSampleSize如果圖像是比屏幕尺寸大很多加載圖像的代碼:

public void loadViewImage(View view, int drawableID) { 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeResource(getResources(), drawableID, options); 
     options.inSampleSize = calculateInSampleSize(options, view.getWidth(), view.getHeight()); 
     options.inJustDecodeBounds = false; 
     view.setBackgroundDrawable(new BitmapDrawable(BitmapFactory.decodeResource(getResources(), drawableID, 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; 

    while (height/inSampleSize > reqHeight || width/inSampleSize > reqWidth) { 
     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) >= reqHeight 
       && (halfWidth/inSampleSize) >= reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 

    return inSampleSize; 
} 

的圖像然後被加載通過:

final RelativeLayout backgroundLayout = (RelativeLayout)findViewById(R.id.backgroundLayout); 
backgroundLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 
     @Override 
     public void onLayoutChange(View v, int left, int top, int right, int bottom, 
            int oldLeft, int oldTop, int oldRight, int oldBottom) { 
      loadViewImage(backgroundLayout, R.drawable.background); 
     } 
    }); 

此應用適用於三星Galaxy S7 Edge,但不適用於LG G2。當使用inSampleSize 2它,但我想知道這些291kb圖像如何使用這麼多的內存。

任何幫助,非常感謝。

+0

首先有更簡單的方法來做這個使用'畢加索'爲android或如果你仍然想要你自己的方式得到它使用所有沉重的邏輯來位圖縮放和計算遠離UI線程線索'AsyncTask ' –

+0

* 291kb images * no,當它們作爲位圖加載時,它們沒有采用這樣的大小...... **文件大小並不重要** – Selvin

+2

'圖像總數爲291kb'。更有意義的是圖像的分辨率。由於內存使用位圖取決於分辨率。現在,如果您使用BitmapFactory.decodeResource()作爲位圖將適用於screan,則您無法控制分辨率。你可以更好地從一個正常的輸入流解碼。 – greenapps

回答

0

人們告訴你尺寸無關緊要。文件大小無關緊要。 GIF vs JPG也不比PNG。重要的是以像素爲單位的圖像大小。位圖對象是未壓縮的,而文件是壓縮的。這意味着每個像素需要4個字節(加上一些小的可以忽略的開銷)。所以1440x2560的圖像大約是370萬像素,大約15MB。每個人都會佔用那麼多的記憶。縮放需要更多 - 你必須解碼至少一部分原件來縮放它(這可能會佔用兩個單獨尺寸的總和)。

通常,當您看到OOM錯誤時,問題是如何在整個代碼中使用內存,而不僅僅是在一個地方。最好的方法來檢查是通過堆分析尋找逃跑對象創建/保留。儘管非常大的圖像(例如來自新設備上常見的12兆像素相機的圖片)可能會在縮放中導致很多問題,但單獨的圖像需要50MB。除非你加載了大量的全屏圖像,否則這應該不成問題。如果是的話,你應該在手工完成時回收它們。如果你有很多這樣的佈局的活動,並且可能有很深的堆棧,你可能要考慮擺脫onPause中的圖像並在onResume中重新加載以節省內存。

相關問題