2012-09-26 88 views
1

這裏是我的代碼:的Android OOM造成繪製成位圖

int[] image = {R.drawable.image1, R.drawable.image2, R.drawable.image1, R.drawable.image2, 
     R.drawable.image1, R.drawable.image2, R.drawable.image1, R.drawable.image2, 
     R.drawable.image1, R.drawable.image2, R.drawable.image1, R.drawable.image2, 
     R.drawable.image1, R.drawable.image2, R.drawable.image1, R.drawable.image2, 
     R.drawable.image1, R.drawable.image2, R.drawable.image1, R.drawable.image2, 
     R.drawable.image1, R.drawable.image2, R.drawable.image1, R.drawable.image2}; 

而且getView:

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     convertView=LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null); 
     ImageView imageView = (ImageView) convertView.findViewById(R.id.imageView); 
     imageView.setBackgroundResource(image[position]); 

     return convertView; 
    } 

一切都很好。沒有OOM。

然後,我想先品嚐繪製:

public static Bitmap sampleImage(Context context, int resourceId, int sampleSize) {   
      Bitmap resizeBmp = null; 
      BitmapFactory.Options opts = new BitmapFactory.Options(); 
      opts.inSampleSize = sampleSize; 
      resizeBmp = BitmapFactory.decodeResource(context.getResources(), resourceId, opts); 

      return resizeBmp; 
     } 

而且新getView:

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     convertView=LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null); 
     ImageView imageView = (ImageView) convertView.findViewById(R.id.imageView); 
     Bitmap item = BitmapUtil.sampleMaskInShelf(getApplicationContext(), image[position], 4); 
     imageView.setImageBitmap(item); 
     //  imageView.setBackgroundResource(image[position]); 

     return convertView; 
    } 

的事情發生了。起初,應用程序不會崩潰。但是使用的內存超過了50MB,在我上下滾動之後,會導致OOM。

的問題是: 1)爲什麼樣的圖像將增加所用的存儲器。 2)如何減少使用的內存,有沒有其他方法?

+0

它是gridview。 – jjLin

回答

5

好像你是在這裏一個ListView工作?

在這種情況下,你會得到更好的服務(希望節省內存顯著量)有幾個步驟:

  1. 你想嘗試重新使用convertView只要有可能。許多文章都是關於如何做到這一點的。 Here is one
  2. 它看起來像你才真正有兩個不同的圖像(image1image2)。似乎每次調用getView()時都要對位圖進行採樣。您可能應該預先計算兩個採樣位圖,然後重複使用這些位圖。
+0

另外,爲什麼不直接在構造函數中對兩個圖像進行採樣,並將字段變量存儲到兩個不同的位圖中。然後,在getView中,只要做 如果(位置%2 == 0) //使用位圖image1 else //使用位圖image2 – dennisdrew

+1

@dennisdrew是啊,那基本上是我在我的意思上建議的2)以上。 –

+0

是的,我只是澄清jjLin :) – dennisdrew

0

的垃圾回收器不會自動爲您處理位圖釋放,所以任何時候你直接指定一個位圖,您需要還呼籲bitmap.recycle()當你用它做一個變量。不這樣做會導致內存泄漏,這就是你所得到的。但是,如果將位圖分配給drawable,然後調用bitmap.recycle(),然後嘗試並使用drawable,則會看到異常,因爲drawable無法訪問回收的位圖。

我在寫類似於你有什麼一個ListView,和我落得這樣做叫位圖。回收位於當前視口上方超過10個槽位的任何位圖,在該ListView項目上設置一個標誌以顯示其位圖已被回收,然後如果用戶滾動回來,則getView重新載入位圖。

0

而是每次創建新的視圖,你應該嘗試重用視圖如..

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    if(v == null) { 
     v=LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null); 
    } 
    ImageView imageView = (ImageView) convertView.findViewById(R.id.imageView); 
    imageView.setBackgroundResource(image[position]); 

    return v; 
} 

以及有關OOM更多的操作,你應該在以下鏈接嚕.. http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

或者你可以使用UniversalImage裝載機庫加載圖像..你可以從 UniversalImageLoader

希望這有助於找到它的圖書館......