NetworkImageView 缓存调整大小的图像而不是原始图像
NetworkImageView caches resized image rather than original
我一直在涉足 Android 开发领域,我一直在使用 Volley 和 LruCache 构建一个基本的新闻 reader 应用程序。
我有一个回收器视图,其中每个单元格都包含来自 Volley 库的 NetworkImageView。我可以点击那个单元格,它会打开另一个 activity,这是一种详细视图,可以在单元格中显示更大版本的图像。在 NetworkImageView 上使用 setImageURL 方法时,我使用相同的 URL,但对我来说很明显,NetworkImageView 将图像的大小附加到它用于在 LruCache 中缓存图像的键.这意味着即使 URL 相同,但两个不同大小的 NetworkImageView 将创建两次网络调用,而不是一次网络调用和一次缓存调用。
在某些方面这是有道理的,为什么要缓存比您需要的更大的图像?但是,我想知道是否可以缓存原始图像而不是调整大小的图像?
我希望这是有道理的,谢谢,大卫。
ImageLoader 的 LruBitmapCache 与 http 缓存不同(默认实现 DiskBasedCache)。在 lru 缓存中,您确实缓存了 eaxct 位图及其将要显示的大小,否则当您需要放入容器时,您将需要在每次连接时对图像数据数组执行一些操作。 http 缓存或 DiskBasedCache 但是缓存原始响应。
所以您仍然进行 2 次调用的原因可能是因为您的图像响应没有允许缓存的缓存 headers。但是,您可以更改此行为并强制执行缓存。您需要自定义 ImageLoader,因为这是创建图像请求的那个。你必须覆盖 "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);
}
};
}
};
...
我一直在涉足 Android 开发领域,我一直在使用 Volley 和 LruCache 构建一个基本的新闻 reader 应用程序。
我有一个回收器视图,其中每个单元格都包含来自 Volley 库的 NetworkImageView。我可以点击那个单元格,它会打开另一个 activity,这是一种详细视图,可以在单元格中显示更大版本的图像。在 NetworkImageView 上使用 setImageURL 方法时,我使用相同的 URL,但对我来说很明显,NetworkImageView 将图像的大小附加到它用于在 LruCache 中缓存图像的键.这意味着即使 URL 相同,但两个不同大小的 NetworkImageView 将创建两次网络调用,而不是一次网络调用和一次缓存调用。
在某些方面这是有道理的,为什么要缓存比您需要的更大的图像?但是,我想知道是否可以缓存原始图像而不是调整大小的图像?
我希望这是有道理的,谢谢,大卫。
ImageLoader 的 LruBitmapCache 与 http 缓存不同(默认实现 DiskBasedCache)。在 lru 缓存中,您确实缓存了 eaxct 位图及其将要显示的大小,否则当您需要放入容器时,您将需要在每次连接时对图像数据数组执行一些操作。 http 缓存或 DiskBasedCache 但是缓存原始响应。
所以您仍然进行 2 次调用的原因可能是因为您的图像响应没有允许缓存的缓存 headers。但是,您可以更改此行为并强制执行缓存。您需要自定义 ImageLoader,因为这是创建图像请求的那个。你必须覆盖 "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);
}
};
}
};
...