【问题标题】:Android OutOfMemory exception - Is there another approach for my needs?Android OutOfMemory 异常 - 还有另一种方法可以满足我的需求吗?
【发布时间】:2012-12-06 16:28:51
【问题描述】:

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

我已经在多次迭代中成功部署了该应用程序,但现在我需要使用更大的基础映像,并且BitmapFactory 在许多设备(新旧设备)上导致了OutOfMemory 异常;似乎任何具有 link 对我没有帮助,因为分辨率/缩放对应用程序的功能至关重要。

我曾尝试在加载前测试设备的可用内存,但结果充其量是参差不齐的(某些设备,如 Galaxy S3 报告大量堆但仍然崩溃)。我也尝试过降低分辨率,但是根据上述测试将图像缩小到安全尺寸时,图像变得无法使用。

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

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

如果需要,我可以发布代码,但你们之前都看过(几乎所有代码都来自 SO)。

提前感谢您的阅读,以及您可以提供的任何帮助。

【问题讨论】:

  • 使用图块(图像的小片段)谷歌地图也是如此。
  • 您可以将位图存储为一组不同分辨率的图块,例如 Google 地图,然后只加载当前可见的图块。另一种选择是使用 OpenGL 像游戏一样实现它。有很多可以管理大型游戏世界的游戏引擎示例。
  • 我见过 OpenGL,但从未使用过。你能推荐一个好的教程吗?
  • @user1810544 - 有很多东西要学。从 Google 的 Android 文档开始。之后,您需要决定是要从头开始编写所有 OpenGL 代码,还是使用 3rd 方游戏引擎。

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


【解决方案1】:

你有几个选择:

  1. 按照 cmets 的建议,将您的大图像分解为图块,将这些图块加载到数组中,然后移动相机对象并仅加载需要绘制的图块。

  2. 缩小图片并使用 'android:scaletype` 放大图片

  3. 在运行时在Canvas 对象上绘制直线和曲线。

  4. 使用 OpenGL

适当的解决方案实际上取决于您希望它的外观。平铺需要更多的开发工作,但看起来会更好,请注意正确清理任何未绘制的平铺...

动态缩放会更容易,但不能保证图像不会模糊。

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

使用 OpenGL 将有最陡峭的学习曲线,并且可能是矫枉过正。这取决于您的目的。

【讨论】:

    【解决方案2】:
    【解决方案3】:

    这里有一些选项:

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

    我已经成功地将这种方法用于无尽的画布,并且效果很好。您实际上只需要绘制用户直接可见的内容。瓷砖是一种丢弃不需要的碎片的方法。瓦片金字塔(您可以在其中对图像进行预下采样并创建更多瓦片),让您能够以干净、快速的方式完成此操作。

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

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

    4) 将您的原始计划转换为 SVG 并使用像 this one 这样的 SVG 库。

    5) 使用“大堆”。我强烈反对这种做法,因为我认为 largeHeap 很少能解决问题,通常有更简洁的方法来解决问题。

    【讨论】:

      【解决方案4】:

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

      https://github.com/ManuelPeinado/ImageLayout

      如果库不支持图像的自动下采样,你应该自己做,以便为当前设备使用最好的图像(这样你就不会得到 OOM)。

      对于自动调整文本大小,您可能会对下一篇文章有​​所了解:

      Auto-fit TextView for Android

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-24
        • 1970-01-01
        • 2022-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-06
        相关资源
        最近更新 更多