Reputation: 482
I’ve been dipping my feet into the world of Android development and I’ve been using Volley and LruCache to put together a basic news reader app.
I have a recycler view where each cell contains a NetworkImageView from the Volley library. I can tap on that cell and it opens up another activity which is a kind of a detail view which displays a larger version of the image in the cell. I use the same URL when using the setImageURL method on the NetworkImageView, but its become apparent to me that the NetworkImageView appends the size of the image to the key it uses to cache the image in the LruCache. This means that even though the URL is the same, two NetworkImageViews of different sizes will create two network calls rather than one network call, and one call to the cache.
In some ways this makes sense, why would you cache an image larger than you need? However, I was wondering if it was possible to cache the original image rather that a resized one?
I hope that makes sense, thanks, David.
Upvotes: 0
Views: 240
Reputation: 3576
LruBitmapCache for the ImageLoader is not the same as the http cache(with default implementation DiskBasedCache). In the lru cache you do cache the eaxct bitmap with the size it going to be displayed as otherwise you will need to perform some operations on the image data array every tie when you need to put in a container. http cache or DiskBasedCache however cache the original response.
So the reason why you make 2 calls anyway is probably because you image responses do not have cache headers that allow caching. However you can change this behaviour and enforce caching. You need to customize ImageLoader as this is the one creating the image requests. You have to override "makeImageRequest" :
...
mImageLoader = new ImageLoader(this.mRequestQueue,
new LruBitmapCache()) {
@Override
protected Request<Bitmap> makeImageRequest(String requestUrl, int maxWidth, int maxHeight,
ScaleType scaleType, final String cacheKey) {
return new ImageRequest(requestUrl, new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
onGetImageSuccess(cacheKey, response);
}
}, maxWidth, maxHeight, scaleType, Config.RGB_565, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onGetImageError(cacheKey, error);
}
}){
@Override
public Response<Bitmap> parseNetworkResponse(NetworkResponse response) {
Response<Bitmap> resp = super.parseNetworkResponse(response);
if(!resp.isSuccess()) {
return resp;
}
long now = System.currentTimeMillis();
Cache.Entry entry = resp.cacheEntry;
if(entry == null) {
entry = new Cache.Entry();
entry.data = response.data;
entry.responseHeaders = response.headers;
}
entry.ttl = now + 30l * 24 * 60 * 60 * 1000; //keeps cache for 30 days
entry.softTtl = now + 24 * 60 * 60 * 1000; // keeps valid(no refresh) for 1 day
return Response.success(resp.result, entry);
}
};
}
};
...
Upvotes: 0