图像真的不是那么大,所以我有点困惑,为什么它们应该导致内存问题.
注意:屏幕分辨率为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个图像之间绘制一些东西).实现这一目标的最佳方法是什么,以尽可能少的内存来获得理想的效果?
背景:
中间:
前景
注意:这只是静态背景,动画发生在它们周围和之间.
解决方法
处理内存使用问题的一些技巧:
如果您没有任何透明度,请在工厂中使用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中读取时,您实际上可以检查所需的大小是否是小于其大小的整数除数,然后指定工厂应在加载时跳过像素.这可以帮助较小分辨率的设备,这些设备具有相应较小的内存限制.
如果您没有单独移动这些背景图像,则将它们全部绘制到单个位图并使用它而不是一次三个.