2012-02-14 15 views
0

我收到了很多來自用戶的這些異常:java.lang.OutOfMemoryError:位圖大小超過了VM預算 - 但我無法在模擬器上重現問題。當從url解碼圖像時出現OutOfMemory

我用這個作爲我的ImageDownloader http://code.google.com/p/android-imagedownloader/source/browse/trunk/src/com/example/android/imagedownloader/ImageDownloader.java#185,並且在嘗試解碼圖像時出現第185行的問題。

關於這個錯誤,還有很多關於stackoverflow的其他問題,但沒有一個符合我的具體情況。在這個問題的解決方案可以工作:https://stackoverflow.com/a/823966但我似乎無法得到它的工作。

以下是我在ImageDownloader改變:

final HttpEntity entity = response.getEntity(); 
if (entity != null) { 
    InputStream inputStream = null; 
    try { 
     inputStream = entity.getContent(); 
     // return BitmapFactory.decodeStream(inputStream); 
     // Bug on slow connections, fixed in future release. 

     FlushedInputStream flushedStream = new FlushedInputStream(inputStream); 

     // Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(flushedStream, null, o); 
     Log.d(LOG_TAG, "decodeStream - outWidth=" + o.outWidth + " outHeight=" + o.outHeight); 

     // The new size we want to scale to 
     final int REQUIRED_SIZE = 70; 

     // Find the correct scale value. It should be the power of 
     // 2. 
     int scale = 1; 
     while (o.outWidth/scale/2 >= REQUIRED_SIZE && o.outHeight/scale/2 >= REQUIRED_SIZE) 
      scale *= 2; 

     // Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     return BitmapFactory.decodeStream(flushedStream, null, o2); 
    } finally { 
     if (inputStream != null) { 
      inputStream.close(); 
     } 
     entity.consumeContent(); 
    } 
} 

它調用decodeStream()第二次失敗時。錯誤是SkImageDecoder :: Factory返回null。我想可能inputStream在第二次調用時關閉或不可用,所以我試圖在上面第一行使用BufferedHttpEntity,但沒有運氣。

有人可以引導我朝着正確的方向嗎?謝謝。

+0

谷歌它有很多關於您的問題的答案:) – RobinHood 2012-02-14 08:38:30

回答

0

解碼首先下載圖像並投入一個字節數組。 decodeStream在使用輸入流時在一段時間後返回null

+0

我試過你的方法,它似乎工作,但我有點擔心下載整個圖像,並把它放在一個字節數組 - 它不會只是導致相同的問題,填充如果同時下載很多大圖像,請記住內存? – 2012-02-14 09:32:57

+0

無論哪種方式,你必須下載完整的圖像。您需要完整的圖像數據進行解碼。但是對於你的方法,當超時發生時該方法會失敗。它會等待一段時間,並返回空值,同時在此時間段內沒有加載完整的imaga數據。更好的方法是嘗試縮放服務器中的圖像。 – Shaiful 2012-02-14 09:47:32

+0

好吧,這是有道理的。但是現在我可以對圖像進行縮減採樣並將其保存在緩存中,而不是整個圖像(取決於大小),希望比以前更好,並節省一些內存。我同意擴展服務器端會更好。 – 2012-02-14 09:57:38

0

首先檢查一次下載多少個圖像。它消耗多少內存在大多數Android手機中有16MB的最大堆內存,當你不需要任何資源時,只需定期釋放(空),它不會讓堆內存增長,並且不會發生內存泄漏問題。這是高內存應用程序(如使用多媒體)時常見的問題之一。所以你所需要做的就是檢查未使用的資源,也不會在將來使用並使它們爲空(例如位圖),因此它將釋放內存。

+0

正如您在原始ImageDownloader源中看到的,位圖被包裝在SoftReference緩存中,所以如果設備內存不足?問題一定是我下載的圖像太大,所以我需要縮小圖像,如果是這種情況 – 2012-02-14 08:58:22

+0

您是將它們存儲到SD卡還是僅保留在應用程序中? – 2012-02-14 10:02:39

0

使用BitmapFactory.Options應該做的事情。即使你是outofmemory,嘗試通過刪除變量清除內存。

而且你在哪裏得到「SkImageDecoder ::廠返回null」在//解碼圖像尺寸或//與inSampleSize

+0

在解碼inSampleSize – 2012-02-14 08:46:34

相關問題