Volley, How many times the onResponse in ImageLoad

2019-02-18 13:24发布

I‘ using Volley to do internet requests. I think the onResponse method should be called only once when receive a response, but I found it called twice.

here is my code:

YVolley.getInstance(context).getImageLoader().get(category.child.get(i).icon, new ImageLoader.ImageListener() {
                @Override
                public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
                    Drawable drawable = new BitmapDrawable(context.getResources(), response.getBitmap());
                    drawable.setBounds(0, 0, GeneralUtil.dip2px(context, 45), GeneralUtil.dip2px(context, 45));
                    button.setCompoundDrawables(null, drawable, null, null);
                    Log.i("swifter", "get icon ... success == "+url);
                }

                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.i("swifter", "get drawable icon error...");
                }
            });

The "success" Log printed twice.

Is there something wrong with my code or it should be like this ?

1条回答
唯我独甜
2楼-- · 2019-02-18 14:15

I found the answer to this in the documentation for ImageLoader.java. The documentation states:

The call flow is this:

  1. Upon being attached to a request, onResponse(response, true) will be invoked to reflect any cached data that was already available. If the data was available, response.getBitmap() will be non-null.

  2. After a network response returns, only one of the following cases will happen:

    • onResponse(response, false) will be called if the image was loaded, or
    • onErrorResponse will be called if there was an error loading the image.

Based on this there are three patterns of possible responses. I have tested and confirmed these in a sample application.

The image is loaded from the cache

In this case there will be one call:

  • onRespsonse(response, true) will be called, and you can get the image from response.getBitmap().

The image is not loaded from cache, and is loaded from the network

In this case there will be two calls:

  • First, onRespsonse(response, true) will be called, and response.getBitmap() will be null.

  • Then, onRespsonse(response, false) will be called, and you can get the image from response.getBitmap().

The image is not loaded from cache, and is not loaded from the network

In this case there will be two calls:

  • First, onRespsonse(response, true) will be called, and response.getBitmap() will be null.

  • Then, onErrorResponse(error) will be called, and details of the error can be found from error (which will be an instance of VolleyError).


In your case, the following code snippet will help you to skip the first "empty" response:

@Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
    // skip cache failure
    if (isImmediate && response.getBitmap() == null) return;

    // ...
}

Hopefully this helps to clear up why you may be getting two responses to your request.

查看更多
登录 后发表回答