2012-12-31 134 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

感谢这些信息的人。 –