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 ?
I found the answer to this in the documentation for ImageLoader.java
. The documentation states:
The call flow is this:
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.
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.