微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android VM不允许我们分配xx字节

我正在开发一款安卓游戏.当我尝试使用3张图像作为背景时问题就出现了.图像为1280x720px和100kb大.
图像真的不是那么大,所以我有点困惑,为什么它们应该导致内存问题.

注意:屏幕分辨率为800×400,因此我无法通过因子2调整图像大小,因为它是suggested on android developer
注意:我正在使用HTC欲望手机(这里崩溃来了),我也尝试过在三星galaxy S1和三星上运行正常.

我已经分析了DDMS中的内存,奇怪的是我发现Heap只有3.5mb大.如果我检查rt.MaxMemory()它说我每个应用程序有大约25mb的空间.

我想到的是,堆没有足够快地“更新”以适应更大的照片/应用程序,所以它在加载图像之前崩溃,尽管它很小.有没有办法手动设置堆大小,或者至少告诉它放大?

这是我加载图像的代码

Bitmap floorFront = BitmapFactory.decodeResource(host.getResources(),R.drawable.floor1);
        floorFront = Bitmap.createScaledBitmap(floorFront,host.realWidth,host.realHeight,true);
        floorFront = Bitmap.createBitmap(floorFront,host.realHeight/2,host.realHeight/2);
        host.addInstance(new Background(0,host,floorFront,1));

        Bitmap floorBack = BitmapFactory.decodeResource(host.getResources(),R.drawable.sand);
        floorBack = Bitmap.createScaledBitmap(floorBack,true);
        floorBack = Bitmap.createBitmap(floorBack,floorBack,4));

        Bitmap floorRock = BitmapFactory.decodeResource(host.getResources(),R.drawable.foreground);
        floorRock = Bitmap.createScaledBitmap(floorRock,true);
        floorRock = Bitmap.createBitmap(floorRock,floorRock,0));

以下是LogCat的确切错误

maxMemory:25165824
 memoryClass:24
 6144000-byte external allocation too large for tgis process.
 Out of memory: Heap Size=4739KB,Allocated=2399KB,Bitmap Size=18668KB
 VM won't let use allocate 6144000bytes

编辑:
现在你说有意义的是位图使用“原始”大小的图像而不是压缩.经过一些研究后,似乎在Android 2.2和2.3位图上没有存储在堆中,因此在加载图像后堆不会增加.

我还有一个问题.我们使用这3张图片作为背景.我们现在将在垂直方向上调整它们的大小,但在水平方向上我们仍然需要它们.所以图像仍然是100x720px左右.我们需要3个图像的问题是,所以我们可以单独绘制它们并获得图层效果(我们可以在2个图像之间绘制一些东西).实现这一目标的最佳方法是什么,以尽可能少的内存来获得理想的效果

背景:

中间:

前景

注意:这只是静态背景,动画发生在它们周围和之间.

解决方法

我不知道你从哪里获得1280 x 720像素位图是100KB.它真的是几兆字节.以字节为单位,它是1280 * 720 *,但是每个像素有多个字节,对于具有透明度的图像通常为4,对于没有透明图像,通常为2.这是手机加载的大量数据.也许您正在引用压缩图像格式版本(如PNG)的大小.

处理内存使用问题的一些技巧:

如果您没有任何透明度,请在工厂中使用Bitmap.Config.RGB_565输入格式.与ARGB_8888相比,这节省了空间.

在AndroidManifest.xml中的application元素上将largeHeap设置为true.

确保您的位图不会根据设备密度等级自动缩放.例如,将它们放在drawable-nodpi中,或者以编程方式禁用自动缩放,或者为多个可绘制文件夹中的每个密度类提供不同的位图.如果您的位图仅在drawable文件夹中,则它将在XHDPI设备上缩放2倍.

回收您不使用的位图,例如:

Bitmap floorFront = BitmapFactory.decodeResource(host.getResources(),R.drawable.floor1);
Bitmap floorFrontScaled = Bitmap.createScaledBitmap(floorFront,true);
floorFront.recycle();
floorFront = null;

Bitmap floorFrontCropped = Bitmap.createBitmap(floorFrontScaled,host.realHeight/2);
host.addInstance(new Background(0,floorFrontCropped,1));

您也可以手动运行System.gc().系统应该在返回OutOfMemoryError之前为您执行此操作,但它不适用于Android中的位图,因为它们在Java之外分配了内存.

请注意,当您在Bitmap中读取时,您实际上可以检查所需的大小是否是小于其大小的整数除数,然后指定工厂应在加载时跳过像素.这可以帮助较小分辨率的设备,这些设备具有相应较小的内存限制.

如果您没有单独移动这些背景图像,则将它们全部绘制到单个位图并使用它而不是一次三个.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐