(凌空库)OOM使用NetworkImageView时, [英] OOM when using NetworkImageView ( of Volley library)

查看:206
本文介绍了(凌空库)OOM使用NetworkImageView时,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 排球库 的<一个href="https://android.googlesource.com/platform/frameworks/volley/+/d62a616ebca5bfa4f9ec5517208e13f2d501b69a/src/com/android/volley/toolbox/NetworkImageView.java"相对=nofollow> NetworkImageView 是一种方便的方法来处理显示来自Web的图片。

Using the Volley library's NetworkImageView is a convenient way to handle showing images from the web.

然而,有一些错误(因为我已经写了<一href="http://stackoverflow.com/questions/16875357/volley-networkimageview-sometimes-doesnt-show-the-error-image">here).

However, it has some bugs (as i've written here).

对,你可以通过使用它的问题是,它c从网页图像不是去$ C $在存储器有效的方式。

One of the issues that you can have by using it is that it doesn't decode the images from the web in a memory efficient way.

这意味着,如果你使用多个NetworkImageView中有一个GridView控件,并且每个显示,有一个未知的分辨率(可能是小,可能很大)的图像,你会最终有一个OOM。

This means that if you use a gridView with multiple NetworkImageView in it, and each shows an image that has an unknown resolution (could be small, could be large), you would end up having an OOM .

作为一个例子,你可以把这个对象的URL是<一个href="https://github.com/danleech/simple-icons/diff_blob/d6f771d1e17a292681228d5bcdc624a60a18c93f/icons/android/android-4096.png?raw=true"相对=nofollow> 这个 ,看看自己有多少内存的应用程序使用显示位图后,相比之前使用了多少。

as an example, you can set the url of this object to be this one and see for yourself how much memory the app uses after showing the bitmap, compared to how much it used before.

我如何修改的方式,NetworkImageView德codeS位图?

How can i modify the way that NetworkImageView decodes the bitmap ?

我可以改变它的一种方法是使C位图它去$ C $,而使用的this法降尺度的

One way I could change it is to make it decode the bitmap while downscaling it to the needed size (or at least set the max of it to the screen size), for example using this method of downscaling .

推荐答案

排球有一个用于图像拟合给定的宽度和高度像你提到的内置的方法。你需要停止使用 NetworkImageView 提供加载图像不使用它的方便的方法。我建议使用以下方法来降低机会OOM错误:

Volley has a built in method for fitting an image to a given width and height like you mentioned. You need to stop using the convenience methods of loading images provided by NetworkImageView which don't use it. I suggest using the following methods to decrease the chance for OOM errors:

  1. 停止使用 NetworkImageView 。使用普通的的ImageView 并实施监听时,它是提供给应用映像。 这是一个prerequisite步2.使用 NetworkImageView 的get()方法可以导致我experience`问题。
  2. 创建一个 ImageLoader的并使用的get()方法,它接收 ImageRequest 。使用可选的构造函数中的了maxHeight 了maxWidth 的作为参数,如果你能。
  3. 当您使用pviously提到的$ P $ 的get() ImageLoader的,保存方法 ImageContainer 引用方法返回,所以你就可以取消请求,如果该请求完成之前的观点被回收。
  4. 提供的 ImageLoader的构造一个很好的实现了 ImageCache 。这将降低冗余解码位图已经上市。
  5. 如果你的架构允许的话,尽量使用循环()方法上的位图,但要小心,不要循环使用那些你可能仍然需要。
  1. Stop using NetworkImageView. Use a regular ImageView and implement the listener to apply the image when it is available. This is a prerequisite for step 2. Using a NetworkImageView with the get() method may lead to problems in my experience`.
  2. Create an ImageLoader and use the get() method which receives an ImageRequest. Use the optional constructor that takes in a maxHeight and maxWidth as parameters if you can.
  3. When you use the previously mentioned get() method in the ImageLoader, save the ImageContainer reference that method returns so you'll be able to cancel a request if the view is recycled before the request completes.
  4. Provide a good implementation for an ImageCache in the ImageLoader constructor. That'll lower the redundancy in decoding bitmaps that are already available.
  5. If your architecture allows it, try to use the recycle() method on the bitmaps, but be careful not to recycle the ones you might still need.

code代码段(2)+(4)

Added Code Samples

Code snippet for (2) + (4)

// assuming sRequestQueue is your static global request queue 
// and `BitmapCache` is a good implementation for the `ImageCache` interface
sImageLoader = new ImageLoader(sRequestQueue, new BitmapCache());

code代码段(3)假设的 ViewHolder 的模式, imageContainer 是其成员之一的 ViewHolder 类。主要适用于任何建筑。

Code snippet for (3) assuming the ViewHolder pattern and imageContainer is a member of the ViewHolder class. The principal applies to any architecture.

// when applying a new view cancel the previous request first

if (imageContainer != null) {
    imageContainer.cancelRequest();
}

// calculate the max height and max width

imageContainer = sImageLoader.get(imageUrl, 
    new DefaultImageListener(image), maxWidth, maxHeight);

默认图像加载器(你可以做你这里):

The default image loader (you can do what you here):

private class DefaultImageListener implements ImageListener {
    private ImageView imageView;

    public DefaultImageListener(ImageView view) {
        imageView = view
    }

    @Override
    public void onErrorResponse(VolleyError error) {
        //handle errors
    }

    @Override
    public void onResponse(ImageContainer response, boolean isImmediate) {
        if (response.getBitmap() != null) {
            imageView.setImageBitmap(response.getBitmap());
        }
    }
}

这篇关于(凌空库)OOM使用NetworkImageView时,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆