【问题标题】:Setting large image in ImageView from res crashes App从 res 中设置 ImageView 中的大图像会导致 App 崩溃
【发布时间】:2012-09-25 00:42:31
【问题描述】:

我想在我的应用程序中使用一个 .png 文件。这张图片相当大,大约 328x32765 像素,大小为 751KB,位于我的 res 文件夹中。我在尝试将此图像设置到我的布局中时收到“java.lang.OutOfMemoryError:位图大小超出 VM 预算”的错误消息。

我不确定它是否相关,但我在同一页面上也有大约 730 个按钮,可以加载并正常工作,但我认为这些按钮可能也占用了大量内存?

无论哪种方式,是否有一个简单的修复方法可以帮助解决此问题或使我的 .png 图像使用更少的内存?

【问题讨论】:

  • 为什么图片那么高?用户应该能够上下滚动吗?如果是这样,您可能想尝试将其切成更小的切片,并将它们放入列表视图中,然后它将仅加载可见切片。
  • 我认为列表视图可能是一个很好的解决方案,唯一的问题是这对我来说需要大量的工作,我只是为一个非常紧张的朋友免费制作一个应用程序日程。所以我可能不得不寻找更简单的选择。
  • @user753964,考虑到您将花费大量时间进行研究、反复试验。我认为 ListView 将成为您的救星和节省时间。实现它的行数不到 20 行——相当少。
  • 我想我对实现这个方法的保留是我在页面上有很多与我的滚动视图一致的其他布局,所以虽然实际的实现相当简单,但它的变化更大的影响在我的应用程序上多一点。但无论如何我可能最终会使用这种方法,如果没有,我知道下次使用它。感谢您的回复!

标签: android imageview out-of-memory


【解决方案1】:

虽然您的图像有 731KB 大,但实际膨胀的位图大小将接近 41 兆字节。 您收到错误是因为设备无法一次分配 41MB

很遗憾,除了加载图像的缩小版本之外,没有其他方法可以解决此问题。

使用 Bitmap.Options 类并指定比例因子:

2 - 表示将每边缩小两倍

3 - 小三倍,......

x - x 小倍

好消息是生成的膨胀位图大小将为 41/(x * x)MB:

2 - 41/4 = 10.25MB

3 - 41/9 = 4.5MB

4 - 41/16 = 2.6MB .....

试试这个并在多个设备上进行测试。

或者,将图像分解成相当小的图像并使用没有边框或分隔线的 ListView,这样您仍然会看到平滑的图像,但 ListView 也会根据需要处理启动和丢弃片段. (请注意,您将失去水平滚动的能力,因为 ListView 仅垂直滚动 - 以防万一您担心)。

【讨论】:

    【解决方案2】:

    Android 无法处理大位图 OOM 错误将发生。它不是 a=unexpected 错误,这是许多开发人员面临的一个大问题。尝试谷歌搜索许多文档,您会发现有关 OOM 错误的解释。我在开发一个application.For Remove this,采样大图像是唯一的方法。

       int scale = "Image byte length" / 320000;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = scale / 2 + scale % 2* 2;
       decryptedimage=BitmapFactory.decodeByteArray(decryptedData,0,decryptedData.length,options);
    

    【讨论】:

      【解决方案3】:

      如教程中所述,位图占用大量内存 关于位图的 android 网站本身

      Displaying Bitmaps

      编辑:

      尝试使用函数“Bitmap.createScaledBitmap(Bitmap, width, height, filter);”或尝试使用教程中提到的“BitmapFactory.Options”类。

      “BitmapFactory.Options”类有很大帮助,因为它的功能本身可以帮助开发人员通过缓存加载的位图来最大限度地减少 VM 加载位图的使用。

      【讨论】:

      • 我得到了位图 factory.options 类来加载我的图像,但如果我希望图像达到它需要的大小,我仍然会收到 VM 错误。如果我删除滚动视图上尝试加载此图像的 730 按钮,这是否有助于我避免出现 VM 错误?
      • 不,删除 730 按钮将无济于事,因为 VM 抱怨无法立即分配请求的内存。对于较小的对象,android 足够聪明,可以根据需要进行初始化和丢弃(页面到“虚拟内存”)。
      • Nar Gar 是对的,问题是,您的应用程序本身会占用分配给应用程序的内存。在您的情况下,如果我没记错的话,您提到的位图是错误的主要来源,因此您不必查看按钮,除非这些按钮也有自己的位图。在另一个说明中,您是否使用 Bitmap 类在您的应用程序中加载多个位图?如果是这种情况,那么为什么不尝试查看代码的那部分。每次应用在可绘制文件夹之外加载位图时,应用往往会占用大量内存。
      • 我的按钮有 2 个自定义图像,一个用于当它坐在那里时,另一个用于按下它时。虽然每个按钮都使用相同的图像,但我没有将它们作为位图读取,而只是直接从 XML 指向 res 源。但我现在更了解手机中的内存是如何分配的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-05
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      相关资源
      最近更新 更多