Android OutOfMemory异常 - 是否有其他方法可满足我的需求?

时间:2012-12-06 16:28:51

标签: android out-of-memory bitmapfactory android-drawable

我的应用正在加载大图像(房屋平面图),然后在图像上绘制触摸反应物体(家具,灯具等)。我的应用程序附带了一个基本图像文件,但对象来自我的数据库中的坐标。

我已经在多次迭代中成功部署了应用程序,但现在我需要使用更大的基础映像,而BitmapFactory在许多设备(旧设备和新设备)上都会导致OutOfMemory异常; < 32MB堆似乎崩溃了)。我已经阅读了有关SO的157个OOM问题,但我担心它们似乎都指向的link对我没有帮助,因为分辨率/缩放对于应用程序的功能至关重要。

我已经尝试在加载前测试设备的可用内存,但结果最多是不稳定的(像galaxy S3这样的设备报告了大量堆但仍然崩溃)。我也试过降低分辨率但是根据上述测试将图像缩小到安全尺寸时图像变得无法使用。

有没有其他方法可以在不使用位图的情况下实现此设计? 我需要:

  • 加载大型基础图像
  • 在基本图像顶部创建可点击的形状,保持其相对于基本图像的位置/比例
  • BONUS :在我的应用程序的iOS版本中,我可以进行SVG样式的文本缩放,因此小对象上的长标签将保留在对象内 而不是在地图上跑(而且直到 图像被缩放)。在android中复制这个会让我很开心 代码猴。

如果需要,我可以发布代码,但你以前都看过它(几乎全部来自SO)。

提前感谢您阅读,并提供任何帮助。

4 个答案:

答案 0 :(得分:3)

你有几个选择:

  1. 将大图像分成多个图块,将这些图块加载到一个数组中,然后移动一个相机对象,只加载需要绘制的图块,如评论所示。

  2. 使用'android:scaletype`

  3. 缩小图片并进行缩放
  4. 在运行时在Canvas对象上绘制线条和曲线。

  5. 使用OpenGL

  6. 适当的解决方案实际上取决于您希望它的外观。平铺将需要更多的开发努力,但看起来会更好,只要小心你正在清理任何没有绘制的瓷砖......

    动态缩放将更容易,但您无法保证图像不会模糊。

    在运行时绘制Canvas对象可以很好地工作 - 只需使用不同宽度的线和圆和矩形等。

    使用OpenGL将具有最陡峭的学习曲线,并且可能过度。这取决于你的目的。

答案 1 :(得分:0)

答案 2 :(得分:0)

以下是一些选项:

1)使用瓷砖。使用切片并动态加载数据。老实说,这是最好的解决方案。使用此解决方案,您可以加载任意大的图像。

我已经成功地将这种方法用于无尽的油漆画布,它的效果非常好。您真的只需要绘制用户可以直接看到的内容。瓷砖是一种抛弃你不需要的东西的方法。瓷砖金字塔(您预先对图像进行采样并创建更多图块),可以让您以干净,快速的方式完成此操作。

2)使用本机代码。本机代码的内存限制与Java代码不同。你可以分配更多的内存。

3)使用OpenGL。再一次,OpenGL的内存限制与Java代码不同。

4)将您的原始计划转换为SVG并使用this之类的SVG库。

5)使用“largeHeap”。我强烈反对这一点,因为我认为大型Heap很少是解决方案,通常有更简洁的方法来处理这个问题。

答案 3 :(得分:0)

如果图像是静态的,您可能希望使用这个漂亮的库:

https://github.com/ManuelPeinado/ImageLayout

如果库不支持对图像进行自动缩减采样,则应自行完成,以便为当前设备使用最佳图像(这样您就不会获得OOM)。

对于自动调整文本大小,您可能会对下一篇文章感兴趣:

Auto-fit TextView for Android