1

我像这样创建 14 个位图对象:

bmp[0]=BitmapFactory.decodeResource(getResources(), R.drawable.a0000);
bmp[1]=BitmapFactory.decodeResource(getResources(), R.drawable.a0001);
bmp[2]=BitmapFactory.decodeResource(getResources(), R.drawable.a0002);
bmp[3]=BitmapFactory.decodeResource(getResources(), R.drawable.a0003);
bmp[4]=BitmapFactory.decodeResource(getResources(), R.drawable.a0004);
bmp[5]=BitmapFactory.decodeResource(getResources(), R.drawable.a0005);
bmp[6]=BitmapFactory.decodeResource(getResources(), R.drawable.a0006);
bmp[7]=BitmapFactory.decodeResource(getResources(), R.drawable.a0007);
bmp[8]=BitmapFactory.decodeResource(getResources(), R.drawable.a0008);
bmp[9]=BitmapFactory.decodeResource(getResources(), R.drawable.a0009);
bmp[10]=BitmapFactory.decodeResource(getResources(), R.drawable.a0010);
bmp[11]=BitmapFactory.decodeResource(getResources(), R.drawable.a0011);
bmp[12]=BitmapFactory.decodeResource(getResources(), R.drawable.a0012);
bmp[13]=BitmapFactory.decodeResource(getResources(), R.drawable.a0013); 

这些位图用于制作背景动画,资源是 14 张 320x480 像素的 jpj 图像。所以我创建了一个自定义视图,然后在 onDraw 方法中调用位图。然后我在手机上测试与我的图像具有相同分辨率的应用程序,它运行流畅,然后我尝试在具有更大分辨率(如 1280x720)的平板电脑上使用该应用程序,但我的背景不适合整个屏幕,所以我研究了如何通过根据设备分辨率制作具有不同分辨率的新位图来填充整个屏幕,结果是这样的:

newWidth= context.getResources().getDisplayMetrics().widthPixels;
newHeight= context.getResources().getDisplayMetrics().heightPixels;

int contador=0;

        do{
             bmp[contador]= Bitmap.createScaledBitmap(bmp[contador], newWidth,                   newHeight,true);
       contador++;
       }while(contador<13);

然后我简单地将这些线放在我的 onDraw 方法上。

   canvas.drawBitmap(bmp[i], 0, 0, null);
    i++;

如果我在手机上测试应用程序,它运行良好,但是当我在平板电脑上测试它时,我会抛出“位图大小超出 VM 预算”错误......所以我进行了更多调查,我得到了以下解决方案:创建原始14个bmp位图对象并制作第二个位图数组,称为bmp2,然后仅在需要时分配位图,然后在我的onDraw方法中像这样清除它:

   bmp2[i]= Bitmap.createScaledBitmap(bmp[i], newWidth, newHeight,true);
  canvas.drawBitmap(bmp2[i], 0, 0, null);
 bmp2[i].recycle();
 bmp2[i]=null;

它可以在我的平板电脑和手机上运行,​​但我认为性能非常差是因为我实时分配图像(在 onDraw 方法上)但是如果我使用回收方法并且不再次分配 bmp2 将不会一个新的bmp2...

所以最后我真正的问题是:如何在显示图像后清除一些内存,然后当我再次需要它时,我可以使用它。谢谢!

4

4 回答 4

1

恐怕没有使用缩放位图进行全屏动画的安全方法。为什么?

让我们数一数。您的每个初始位图都是 320x480,是吗?那是 320*480*4*14=8601600,大约是 8Mb 的内存。缩放到 1280x720 时,加起来 1280*720*4*14=51609600 字节,即 49 兆字节。49 + 8 = 57 兆字节。鉴于最新的平板电脑最多为您的应用程序 VM 分配了 64 兆字节,因此它不适合使用也就不足为奇了。即使它适合您的平板电脑,如果 Nexus 10 所有者购买您的应用程序会怎样?N10 有 2560×1600 的分辨率(更不用说缩放的位图看起来很可怜​​)。

恐怕为单帧分配单个位图很难让你有一个流畅的动画。您可以尝试一次保留 5 个位图的窗口并回收其他位图,但我仍然认为这还不够。除此之外,这会消耗大量 CPU 工作来进行恒定位图缩放,并且会损坏您的电池。

如果您真的想要动画背景,您可能应该查看 OpenGL 或TextureView

于 2013-05-20T09:00:29.787 回答
1

其他人已经提到如何放大小位图以填充大屏幕不会产生高质量的结果。但无论如何,要回答您的具体问题,这就是您如何绘制放大的低分辨率位图以填充屏幕而不会出现内存错误。

您需要使用其中一种Canvas.drawBitmap()可以在绘图时将位图缩放到正确大小的替代方法。

例如:

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)

Javadoc

绘制指定的位图,自动缩放/平移以填充目标矩形。

dst矩形设置为您之前计算的屏幕大小。然后,您不需要在内存中创建单独的缩放位图,这样您的问题就消失了。

于 2013-05-20T09:42:44.713 回答
0

您应该为您的平板电脑和其他更高屏幕设计新的位图,并将它们放在 res 目录下的 xhdpi 文件夹中。这是最有效的选择。让 Android 操作系统本身为您提取最合适的资源。

请参阅此以获得更详细的帮助 http://developer.android.com/training/multiscreen/index.html

这就是文档所说的

尽管系统执行缩放和调整大小以使您的应用程序在不同的屏幕上工作,但您应该努力针对不同的屏幕尺寸和密度优化您的应用程序。通过这样做,您可以最大限度地提高所有设备的用户体验,并且您的用户相信您的应用程序实际上是为他们的设备设计的,而不是简单地拉伸以适应他们设备上的屏幕。

于 2013-05-20T08:23:36.613 回答
0

大多数时候GC会做这项工作。

您应该有不同的位图分辨率,由 Android 按文件夹(xhdpi、hdpi 等)处理。

您还应该检查BitmapFactory.Options以获得由您的BitmapFactory签名生成的低质量版本位图。

编辑

您可能还需要考虑对位图使用Wea​​kReferences

于 2013-05-20T08:27:46.863 回答