【问题标题】:Application suddenly won't load Bitmap应用程序突然无法加载位图
【发布时间】:2011-08-22 20:17:53
【问题描述】:

我正在开发一款即将完成的 Android 游戏,但在上周,游戏中使用的位图资源的加载突然引发了内存错误。

特别是它引发错误的主要位图是 237kb 和 1792X1024(32 位)。这是一个玩家的精灵表,这就是为什么它这么大,奇怪的是它用来加载,我实际上可以加载一个图像,它是 400X800 32bit 文件的游戏地图,它是 413KB 没有任何问题(这不是错字,较小的分辨率/相同位文件看起来更大。我不完全确定为什么,但我假设它与所涉及的颜色或精灵表主要是透明的事实有关)。所有图像均在 GIMP 中创建。

我不确定是什么导致了错误,因为除了更新 android API 之外,代码中的任何内容都没有变化(尽管在早期测试之前它会随机给出错误)。我还尝试在一个新项目中仅加载这个 spritesheet 本身,它会引发错误,但不是在另一个更大的文件中。

为了让事情变得更奇怪,我有一个从测试手机备份的 APK,当游戏没有引发错误时,我什至尝试解码 png spritesheet 并使用这个精确的图像(它仍然会抛出错误)。让它不抛出错误的唯一方法是将 VM 最大堆增加到 24MB 以上(我尝试过的默认最小堆是 48MB,这很有效,但加载速度比以前慢了很多)。

这可能是一个明显的问题,还是 SDK 中发生了我不知道的更改?几天来,我一直在尝试解决这个问题,尝试了我在许多板上找到的不同方法,包括使用Bitmap.options 设置样本大小、清单调整、在调整大小时更改它、System.gc()recycle() 等。

有人知道这里会发生什么吗?

【问题讨论】:

  • 位图的重要大小不是压缩大小(您在此处说明),而是未压缩位图在内存中的大小,对于 1792x1024 位图,它将接近 8 MB,只有 1.3 MB 为您的 400x800 位图。
  • 请显示您的 LogCat 输出。
  • 你说你还有旧的 APK——它在新的 Android API 上可以正常运行还是现在也抛出错误?
  • 奇怪的是,是的,当我卸载新的 adb install 后,旧的仍然有效。还有一点需要注意的是,当我增加内存时,新的尺寸看起来像屏幕尺寸增加了一倍(换句话说,游戏/布局被绘制得比以前更小,而不是填满屏幕)。可能是manafest中的某些更改导致了这种情况吗?
  • 日志猫和做内存分析/调试基本上告诉我精灵表是问题(我将减小大小来修复它,除非有人能告诉我一个可以修复它的清单更改原样)。复制如下:08-23 13:27:27.191: ERROR/dalvikvm-heap(266): 16515072-byte external allocation too large for this process。 08-23 13:27:27.191:错误/(266):VM 不允许我们分配 16515072 字节 08-23 13:27:27.191:调试/AndroidRuntime(266):关闭 VM 08-23 13:27: 27.191: WARN/dalvikvm(266): threadid=3: thread exiting with unaught exception (group=0x4001b188) etc.

标签: android memory bitmap heap-memory


【解决方案1】:

我怀疑您的实际内存位图是否真的是 237KB。我猜你有一个 237KB 的 PNG,但解码后的位图在内存中要大得多。 PNG 使用一种无​​损压缩形式。至于为什么它以前有效但现在无效,我不确定,但我一点也不惊讶你用那么大的位图耗尽内存。

您可以使用工具来压缩/生成精灵表。像这样的东西可能有用:

http://spritesheetpacker.codeplex.com/

【讨论】:

  • 是的,它是 png 不是位图,它是位图对象就是我的意思。我想我最终会通过调整动画上相机的 POV 并仅旋转精灵表来减小尺寸。
【解决方案2】:

如果您遇到 OutOfMemory 错误,那么我遇到了同样的问题,并按如下方式进行了修复。我真的认为这是本机位图代码中的一个错误。

这是我所做的:不要使用BitmapFactory.decodeStreamBitmapFactory.decodeFile。而是使用BitmapFactory.decodeFileDescriptor

如果这对您有用,请告诉我,因为这将有助于确认其他方法中是否确实存在错误。

【讨论】:

  • 我其实是用BitmapFactory.decodeResource(getResources(),R.drawable.image),有没有对应的重载方法从R.java文件中拉入?
  • 我认为你可以做一些类似 resources.openRawResourceFD(R.drawable.image).getFileDescriptor()
  • 我最终只是通过制作一个定向精灵并旋转它们来减小位图的大小(对对齐进行一些调整)。这在一定程度上消除了 3d 效果,但在这种情况下应该没问题。仍然不确定为什么这突然开始抛出错误,但我打算在优化阶段最终减小图像大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多