【问题标题】:Displaying images from byte array from server in Android在Android中显示来自服务器的字节数组中的图像
【发布时间】:2012-04-30 14:33:02
【问题描述】:

我的 Android 应用程序连接到服务以从我们的服务器请求文件。在请求时,文件类型未知,但服务器会回复一个 Hashmap,其中包含文件扩展名和文件数据的字节数组。

然后,我的移动应用程序会获取这些数据,如果它是 jpg、png、txt 或 html 文件,它将在屏幕上显示该文件。如果是不同的文件类型,则会创建一个文件并提示系统尝试在外部应用程序中打开该文件。

文本、html 和外部文件都可以正常工作。对于我加载的第一张图片,图片工作正常,但如果我再次调用服务器以加载列表中的下一张图片,我经常会收到此错误:

   E/AndroidRuntime(390): java.lang.OutOfMemoryError: bitmap size exceeds VM budget

我正在使用相同的服务器调用,并将新信息存储在旧信息之上。 这是我实际加载图像数据的代码:

  imageView.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.length));

有没有办法处理内存问题,使我的应用程序不会崩溃?我已经尝试从服务器端缩小图像以使它们更小更易于管理(但这似乎是一个创可贴而不是适当的修复。)目前我只是使用原始字节和 BitmapFactory 来加载 imageView,但如果有其他方法,我总是可以用实际的 png 或 jpg 创建一个临时文件,如果这有任何帮助的话。

有人可以就处理此问题的最佳方法提供一些建议吗?

【问题讨论】:

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


    【解决方案1】:

    图片占用了您的应用所拥有的几兆 RAM。应用程序需要在内存中保存的 1 兆像素 = 4 兆字节的原始图像数据(至少 RGBA_8888 模式)。多个大图像会在任何设备上崩溃。

    • 将图像下载到文件系统,从那里使用它们并使用sample size > 1 对其进行解码,如果它们比您需要的更大/您有内存。
    • 如果您不需要它们,请立即recyle() 图片。他们的原生缓冲区不能很好地与 GC 配合使用。

    【讨论】:

    • 将图像加载到文件系统后如何显示它们?我在什么时候回收图像?我尝试在早期版本的代码中对我的位图数据调用 bitmap.recylce()。你说的是这个还是别的什么?
    • BitmapFactory 可以直接从文件加载。如果您加载图像 A,然后调整其大小使其变为 B,您可以在该点回收 A。每当您知道不再需要图像时。
    • 我发现服务器没有像预期的那样调整图像的大小,我仍然得到 5+mega 像素的图像,这正在消耗内存。我仍然使用了你建议的技巧,而且一切似乎都很好。谢谢。
    【解决方案2】:

    首先确保以适合屏幕的方式对位图进行解码和缩放。 在设置新位图之前,还要从 imageView 中回收位图。您要么需要保留对解码位图的引用,要么像这样访问旧位图。

        Drawable d = imageView.getDrawable();
        if (d!=null && d instanceof BitmapDrawable){
            BitmapDrawable bd = (BitmapDrawable)d;
            bd.getBitmap().recycle();
        }
    

    【讨论】:

      猜你喜欢
      • 2018-08-17
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 2013-06-30
      • 1970-01-01
      相关资源
      最近更新 更多