2013-07-20 73 views
0

我有人在我的應用程序中加載一堆圖像時出錯,我不確定是什麼原因導致它。獲取異常OutofMemoryError

這是他得到的錯誤。 LINE 135位於底部。
我在想他的手機內存不足。他正在使用2010年製作的Desire HD。該方法所做的是從服務器獲取圖像並將其保存在散列圖中。隨着顯示在屏幕上。關於如何防止這種OUTMEMORYERROR的任何想法?

我在想如果有超過20個圖像,設置一個計數器,只清除哈希映射。

的logcat:

java.lang.RuntimeException: An error occured while executing doInBackground() 
at android.os.AsyncTask$3.done(AsyncTask.java:200) 
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
at java.lang.Thread.run(Thread.java:1019) 
Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 
at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657) 
at com.codalata.craigslistchecker.GETTHEIMAGE$ITask.doInBackground(GETTHEIMAGE.java:135) 
at com.codalata.craigslistchecker.GETTHEIMAGE$ITask.doInBackground(GETTHEIMAGE.java:1) 
at android.os.AsyncTask$2.call(AsyncTask.java:185) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 

代碼:

public class GETTHEIMAGE { 

private HashMap<String, Drawable> ICache; 
private static Drawable DefIcon = null; 
private BaseAdapter adapt; 
private ItemView item; 
private int num = 0; 

public GETTHEIMAGE(Context c) { 
    ICache = new HashMap<String, Drawable>(); 
} 

public Drawable GetTheImagedata(
     com.codalata.craigslistchecker.Favorites.TheListAdapter theListAdapter, 
     ImageView ICON_IMG) { 
    this.adapt = theListAdapter; 
    String url = (String) ICON_IMG.getTag(); 
    if (ICache.containsKey(url)) { 
     return ICache.get(url); 
    } else { 
     new ITask().execute(url); 
     return DefIcon; 
    } 
} 

public Drawable GetTheImagedata(TheListAdapter adapter, ImageView ICON_IMG) { 
    this.adapt = adapter; 
    String url = (String) ICON_IMG.getTag(); 
    if (ICache.containsKey(url)) { 
     return ICache.get(url); 
    } else { 
     new ITask().execute(url); 
     return DefIcon; 
    } 
} 

public Drawable GetTheImagedata2(ItemView itemView, String string) { 
    this.item = itemView; 
    String url = string; 
    if (ICache.containsKey(url)) { 
     return ICache.get(url); 
    } else { 
     new ITask2().execute(url); 
     return DefIcon; 
    } 
} 

private class ITask2 extends AsyncTask<String, Void, Drawable> { 
    private String Nick; 

    @Override 
    protected Drawable doInBackground(String... params) { 
     Nick = params[0]; 
     InputStream isImage = null; 
     try { 
      URL url = new URL(Nick); 
      isImage = url.openStream(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return Drawable.createFromStream(isImage, "Nick"); 
    } 

    @Override 
    protected void onPostExecute(Drawable result) { 
     super.onPostExecute(result); 
     if (num == 0) { 
      item.ivItemimage1.setImageDrawable(result); 
     } 
     if (num == 1) { 
      item.ivItemimage2.setImageDrawable(result); 
     } 
     if (num == 2) { 
      item.ivItemimage3.setImageDrawable(result); 
     } 
     if (num == 3) { 
      item.ivItemimage4.setImageDrawable(result); 
     } 
     if (num == 4) { 
      item.ivItemimage5.setImageDrawable(result); 
     } 
     if (num == 5) { 
      item.ivItemimage6.setImageDrawable(result); 
     } 
     if (num == 6) { 
      item.ivItemimage7.setImageDrawable(result); 
     } 
     if (num == 7) { 
      item.ivItemimage8.setImageDrawable(result); 
     } 
     if (num == 8) { 
      item.ivItemimage9.setImageDrawable(result); 
     } 
     if (num == 9) { 
      item.ivItemimage10.setImageDrawable(result); 
     } 
     num++; 
    } 
} 

private class ITask extends AsyncTask<String, Void, Drawable> { 
    private String Nick; 

    @Override 
    protected Drawable doInBackground(String... params) { 
     Nick = params[0]; 
     InputStream isImage = null; 
     try { 
      URL url = new URL(Nick); 
      isImage = url.openStream(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     try{ 
LINE 135 ----->   return Drawable.createFromStream(isImage, "Nick"); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Drawable result) { 
     super.onPostExecute(result); 
     synchronized (this) { 
      ICache.put(Nick, result); 
     } 
     adapt.notifyDataSetChanged(); 
    } 
} 
} 
+0

20圖像的控制。每幅圖像的大小是多少?如果它太大,你需要縮小它們。此外它更好地緩存在SD卡/內部手機內存的圖像。 – Raghunandan

+0

一些圖像很小,像200x200x和一些像1000x1000x大,問題是我需要立即擺脫它們。因爲這些傢伙手機很舊,無法處理緩存中的大量圖像。 – Xjasz

回答

1

你需要按比例縮小的位圖,並在內存中加載一個縮小版本。

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Use appropriateBitmapFactory.decode method as needed.

下面是一個例子:

Out of Memory error with Bitmap

注:就Android 3.0(API級別11),像素數據被一起存儲在Dalvik的堆與相關的位圖。

在Android 2.3.3(API等級10)及更低版本中,建議使用recycle()。如果您在應用中顯示大量的位圖數據,則可能會遇到OutOfMemoryError錯誤。 recycle()方法允許應用程序儘快回收內存。

Android 3.0(API Level 11)引入了BitmapFactory.Options.inBitmap字段。如果設置了此選項,則在加載內容時,採用Options對象的解碼方法將嘗試重新使用現有的位圖。這意味着位圖的內存被重用,從而提高了性能,並消除了內存分配和解除分配。

http://developer.android.com/training/displaying-bitmaps/manage-memory.html

+0

謝謝我一定會考慮這個 – Xjasz

+0

@Xjasz也檢查這個懶加載http://stackoverflow.com/questions/16789676/caching-images-and-displaying/16978285#16978285 – Raghunandan

0

在你第一次的AsyncTask類num++;總是越來越多,所以在它超越分配給該程序的內存空間一定的價值,你應該把該

+0

異步類ITask2是爲了別的我最大它在10,因爲沒有人可以獲得10張圖片。 ITask就是這個錯誤發生的地方。我將刪除一些看起來很雜亂的代碼 – Xjasz

+0

@Xjasz如果你在應用中顯示大量的位圖數據,你可能會遇到OutOfMemoryError錯誤。如果圖像太大,您可能會遇到內存泄漏。所以縮小你的位圖。 20張圖片不應導入OOM。 http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html。還檢查文檔中的緩存位圖。 – Raghunandan

+0

你確定沒有人能達到10?即使沒有人可以達到10,10以下的圖像數量也可以導致OutOfMemory,你應該減少圖像文件的大小/分辨率 –

相關問題