2013-05-22 40 views
2

最新的人。BitmapFactory OutOfMemory

我試圖做一個產品目錄,這是我在做什麼:

  • 活動與ViewPager - 每一件產品都是在這個ViewPager片段。 - 每個片段都有一個畫廊。

我從網上下載產品數據和圖像並將圖像存儲到SD卡中。

但我的應用程序保持崩潰,這是錯誤

05-22 10:04:43.829: E/AndroidRuntime(12388): FATAL EXCEPTION: main 
05-22 10:04:43.829: E/AndroidRuntime(12388): java.lang.OutOfMemoryError 
05-22 10:04:43.829: E/AndroidRuntime(12388): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
05-22 10:04:43.829: E/AndroidRuntime(12388): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493) 
05-22 10:04:43.829: E/AndroidRuntime(12388): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299) 
05-22 10:04:43.829: E/AndroidRuntime(12388): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:324) 

我用的是getView在畫廊的轉接器內德位圖的工廠,但是當我刷卡片段崩潰。然後,我更改並創建和主要活動創建時列表,但現在如果我關閉活動,並嘗試再次打開它,崩潰,然後如果我嘗試再次打開它正常打開。

我做錯了什麼?有更好的方法來做到這一點?

這是我的適配器圖庫

public class ImagemAdapter extends BaseAdapter { 

     private Context ctx; 
     List<Bitmap> pics; 

     public ImagemAdapter(Context c, List<Bitmap> pics) { 
      ctx = c; 
      this.pics = pics; 
     } 

     @Override 
     public int getCount() { 

      return pics.size(); 
     } 

     @Override 
     public Object getItem(int position) { 
      return pics.get(position); 
     } 

     @Override 
     public long getItemId(int position) { 
      return position; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent){ 
      if(convertView == null){ 
       int arquivoLayout = R.layout.adp_galeria; 
       LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       convertView = inflater.inflate(arquivoLayout, null); 
       ImageView img = ((ImageView)convertView.findViewById(R.id.imgProd));    
       img.setImageBitmap(pics.get(position)); 
      } 
      return convertView; 
     } 

} 

另一個奇怪的是,該適配器上的convertView總是空。

編輯:

我認爲問題是位圖保留在內存中。 當片段的onCreateView叫,我填充圖像列表我應該顯示,當片段的onDestroyView叫,我這樣做:

for(int i =0; i< imagemBit.size(); i++){ 
    Bitmap bmp = imagemBit.get(i); 
    bmp.recycle(); 
    bmp = null; 
} 
imagemBit.clear(); 

但是:當onCreateView再次(被叫用戶返回到前一頁)當我嘗試再次填充列表時,應用程序與OutOfMemory異常崩潰。

+0

使用視圖持有人的性能和平滑滾動。如果圖片尺寸太大,縮小尺寸 – Raghunandan

+0

如果convertView始終爲空,如何使用視圖保持器? – JannGabriel

+0

http://developer.android.com/training/improving-layouts/smooth-scrolling.html – Raghunandan

回答

2

請看看this answer
我在下載內容時遇到了同樣的問題,並且顯示了許多帶有緩存的圖像。確保只有一些圖像(取決於大小)保留在內存中。

+0

如何從內存中取消分配映像? – JannGabriel

+0

由於用於解碼位圖的內存是本地分配的,而不是在堆中分配,所以GC將它釋放更復雜。幸運的是,Bitmap具有recycle()方法,可立即釋放內存。 – ooops

+0

我使用for循環內的recycle()來釋放列表中的每個iten,並且他們使用list.clear()。但仍然有OutOfMemory異常 – JannGabriel

1

你的應用崩潰在你的代碼?

我認爲,關閉應用程序後,'圖片'仍然保留對位圖的引用,這就是GC不釋放位圖的原因。您必須在應用程序停止或創建新位圖之前釋放位圖。

+0

這就是對的。它保留引用,因爲它在嘗試再次加載bitmapfactory時崩潰。我試圖添加大量的照片,它總是崩潰。我認爲其他問題與圖像的大小有關。你知道如何處理大量的大圖片嗎? – JannGabriel

+0

你必須使用一些在背景中運行的圖像加載器。如果您的圖片來自網絡,則可以使用android查詢:https://code.google.com/p/android-query/downloads/detail?name=android-query-full.0.24.3.jar。請閱讀https://code.google.com/p/android-query/#Image_Loading。如果沒有,也許這個lib可以幫助你。如果不是,我推薦的概念是:使用位圖數組,位圖詳細數組。如果它們不爲null,則開始回收它們。使用AsyncTask按照您的位圖細節創建位圖。 – Alex248

+0

男人,我使用和陣列的位圖創建片段的onCreateView並摧毀它onDestroyView。它在打開應用程序之前崩潰。我究竟做錯了什麼? – JannGabriel