Volley, ImageLoader.ImageListener 中的 onResponse 调用了多少次

Volley, How many times the onResponse in ImageLoader.ImageListener called

我‘使用 Volley 进行互联网请求。我认为 onResponse 方法应该在收到响应时只调用一次,但我发现它调用了两次。

这是我的代码:

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...");
                }
            });

"success" 日志打印了两次。

是我的代码有问题还是应该是这样的?

我在 the documentation for ImageLoader.java 中找到了答案。文档指出:

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.

基于此,存在三种可能的响应模式。我已经在示例应用程序中测试并确认了这些。

图像从缓存中加载的

在这种情况下会有一个电话:

  • onRespsonse(response, true)会被调用,你可以从response.getBitmap().
  • 获取图片

图片不是从缓存加载,从网络加载

在这种情况下会有两个调用:

  • 首先调用onRespsonse(response, true)response.getBitmap()会调用null

  • 然后会调用onRespsonse(response, false),可以得到response.getBitmap()的图片。

图像不是从缓存加载的,不是从网络加载的

在这种情况下会有两个调用:

  • 首先调用onRespsonse(response, true)response.getBitmap()会调用null

  • 然后,onErrorResponse(error)将被调用,错误的详细信息可以从error中找到(这将是VolleyError的一个实例)。


对于您的情况,以下代码片段将帮助您跳过第一个 "empty" 响应:

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

    // ...
}

希望这有助于弄清楚为什么您的请求可能会收到两个回复。