2012-12-31 170 views
16

我正在研究在ViewPager中顯示12個視圖的遊戲簿應用程序。 這是我的自定義PagerAdapter:Android setBackgroundResource導致內存不足excepiton

private class ImagePagerAdapter extends PagerAdapter { 

    private int[] mImages = new int[] { R.drawable.copertinai, 
      R.drawable.blui, R.drawable.azzurroi, R.drawable.rossoi, 
      R.drawable.gialloi, R.drawable.verdei, R.drawable.rosai, 
      R.drawable.grigioi, R.drawable.neroi, R.drawable.arancionei, 
      R.drawable.marronei, R.drawable.violai, R.drawable.ulm }; 

    @Override 
    public int getCount() { 
     return mImages.length; 
    } 

    @Override 
    public boolean isViewFromObject(View view, Object object) { 
     return view == ((RelativeLayout) object); 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container, int position) { 
     Context context = MainActivity.this; 
     RelativeLayout relLayImageView = new RelativeLayout(context); 
     relLayImageView.setBackgroundResource(mImages[position]); 

     ((ViewPager) container).addView(relLayImageView, new LayoutParams(
       LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 
     return relLayImageView; 
    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     ((ViewPager) container).removeView((RelativeLayout) object); 
     object=null; 
     System.gc(); 
    } 
} 

在某些設備上會導致內存不足exceptionr隨機當這行代碼被稱爲

relLayImageView.setBackgroundResource(mImages[position]); 

但我看到這樣的事情在所有設備logcat當我翻頁:

12-31 00:25:31.655: I/dalvikvm-heap(9767): Grow heap (frag case) to 50.875MB for 10384016-byte allocation 

該應用程序也崩潰在相同的問題,當在另一個活動我設置不同的背景資源基於用戶行爲的主要佈局。下面的代碼:

  btn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 


       colorButtons.get(indiceColoreAttuale).setBackgroundResource(
           unSelectedColorsRes[indiceColoreAttuale]); 

       switch (index) { 
       case 0: 
        mainLayout.setBackgroundResource(R.drawable.blus); 
        break; 
       case 1: 
        mainLayout 
          .setBackgroundResource(R.drawable.azzurros); 
        break; 
       case 2: 
        mainLayout 
          .setBackgroundResource(R.drawable.rossos); 
        break; 
       case 3: 
        mainLayout 
          .setBackgroundResource(R.drawable.giallos); 
        break; 
       case 4: 
        mainLayout 
          .setBackgroundResource(R.drawable.verdes); 
        break; 
       case 5: 
        mainLayout 
          .setBackgroundResource(R.drawable.rosas); 
        break; 
       case 6:      
        mainLayout 
          .setBackgroundResource(R.drawable.grigios); 
        break; 
       case 7: 
        mainLayout 
          .setBackgroundResource(R.drawable.neros); 
        break; 
       case 8: 
        mainLayout 
          .setBackgroundResource(R.drawable.arancios); 
        break; 
       case 9: 
        mainLayout 
          .setBackgroundResource(R.drawable.marrones); 
        break; 
       case 10: 
        mainLayout 
          .setBackgroundResource(R.drawable.violas); 
        break; 
       } 

       mainLayout.startAnimation(animationShowTextColor); 
       mainLayout.setGravity(Gravity.CENTER_HORIZONTAL); 
       indiceColoreAttuale = index; 
       colorButtons.get(index).setBackgroundResource(
         selectedColorsRes[index]); 

      } 
     }); 

它再次運行excepiton當我打電話setBackgroundResource()上mainLayout。

我希望你能幫助我解決這個問題,在此先感謝!這可以通過Dalvik虛擬機可以使用

+0

聽起來你正在加載一些_huge_的背景和設備沒有足夠的內存給他們...... –

+0

是的,但有時會發生在有大量內存的設備上,並且不會發生在內存較少的設備中。加載不是很大的圖像(從50到200 kb)。 – TheModularMind

+0

他們聽起來不像_huge_。在更改背景資源之前,您可以自己嘗試「回收」位圖。獲取舊的可繪製背景,並在更改後查看它是否爲「BitmapDrawable」,如果它在其「Bitmap」上調用「recycle()」。 –

回答

57

我解決了!你所有的提示都很好,但真正的問題是「/ drawable」文件夾!我在「/ drawable」通用文件夾中的所有圖片都被系統認爲是「/ drawable/mdpi」,所以當我在使用hdpi或更高版本的設備上運行時,圖像被調整大小,並且變得太大而導致OutOfMemoryException!

現在,我使用「/繪製-nodpi」來存儲我的圖片。此文件夾的工作方式類似於「/ drawable」,但圖像永遠不會調整大小!

+1

我想你的意思是'drawable-nodpi' –

+0

謝謝,作品像一個魅力! – ElDoRado1239

+0

我注意到內存使用量顯着下降。這個解決方案有什麼缺點嗎? –

8

每個Android應用具有有限的存儲器(堆)。在一些設備上它是32 MB,它是64 MB。當您設置後臺資源時,您會在堆上加載該資源。該資源被加載爲位圖 - 它的大小是寬*高*像素大小。 Usualy位圖加載爲ARGB圖像,每個像素有4個字節。這表示加載1024x768圖像需要1024 * 768 * 4 = 3145728 B = 3072 kB =堆上3 MB。當你加載大量的大圖像時,它會消耗所有空閒的堆內存並導致內存不足異常。

爲了解決這個問題最好是小到可以載入圖像 - 當你在顯示圖像的縮略圖就足以將其加載到這是不是遠遠大於是顯示器的具體部分的分辨率分辨率。這意味着當您在800x600顯示器上顯示圖像時,加載1024x768圖像是不夠的。您可以使用BitmapFactory以較小的分辨率加載圖像。

使用方法decodeResource(activity.getResources(),R.drawable.imageId,opts)。 BitmapFactory.Options opts的參數爲inSampleSize,您可以在其中設置圖像的二次採樣。在不需要透明度的情況下,參數inPreferredConfig可用於設置RGB_565而不是ARGB_8888。

+0

感謝這些信息的人。 –