问题:我有X数量的ImageViews,我正在动态添加,如下所示:
for (int i=2; i < result.size(); i++) {
// instantiate image view
ImageView mImageView = new ImageView(this);
mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
mImageView.setBackgroundResource(R.drawable.selectable_background_theme);
mImageView.setOnClickListener(this);
// download image and display it
mImageLoader.get(result.get(i), ImageLoader.getImageListener(mImageView, R.drawable.ic_logo, R.drawable.ic_action_refresh));
// add images to container view
mLlDescContent.addView(mImageView);
}
希望能够点击图像并在另一个活动中全屏显示。我已经阅读了一些方法,例如传递Uri或将实际位图作为字节数组传递。
问题:如何获取我使用Volley ImageLoader下载的Uri或实际位图。我使用的LruCache是我在这里找到的BitmapLruCache:Android Volley ImageLoader-BitmapLruCache参数。有人能帮我实现这个目标吗。
我在上面的代码后尝试了这个,但什么都没有:
Bitmap mBitmap = VolleyInstance.getBitmapLruCache().getBitmap(result.get(2));
mIvAuthorImg.setImageBitmap(mBitmap);
编辑:如果我用重新请求图像
mImageLoader.get(result.get(i), ImageLoader.getImageListener(mImageView, R.drawable.ic_logo, R.drawable.ic_action_refresh));
图像是从缓存中加载的,但如果我尝试使用直接从缓存中访问图像
Bitmap mBitmap = VolleyInstance.getBitmapLruCache().getBitmap(result.get(2));
mIvAuthorImg.setImageBitmap(mBitmap);
图像不会加载。我希望能够处理图像,比如在将其传递给下一个活动之前调整一个东西的大小。
Volley依赖于缓存的实现来实现成功高效的缓存。ImageLoader
的构造函数采用ImageCache
,这是Volley中保存和加载位图的一个简单接口。
public ImageLoader(RequestQueue queue, ImageCache imageCache)
引用ImageCache
接口的Javadoc:
简单的缓存适配器接口。如果提供给ImageLoader,它将在调度到Volley之前用作一级缓存。实现不能阻止。建议使用LruCache实现。
达尔文是对的。如果您请求一个图像,并且该图像存在于缓存中,则它将从缓存加载,而不是从web加载。这应该是您的情况,因为您正在加载并呈现一个图像,如果单击该图像,则应在新活动的缓存中显示该图像。
你说它不起作用,也许你的实现没有针对你的用例进行优化。你用的是哪种缓存?您是否有Volley团队推荐的集中式RequestQueue
和ImageLoader
?
看看这个问题,它和你的问题不完全一样,但可能对你有帮助。它有一个简单的LRU缓存实现。
希望能有所帮助!
编辑:
Volley的重点不在于担心实现细节。你想要一张照片吗?它将以最好、最快的方式为您加载(从内存加载,如果不通过网络加载)。这正是你应该看待它的方式。检索缓存然后查看它不是正确的方法
现在,如果你想操作位图,你有几个选项,最好的IMO是实现你自己的Image Listener
,将它传递给get()
方法,而不是默认的方法。
类似这样的东西:
public class MyImageListener implements ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
// handle errors
}
@Override
public void onResponse(ImageContainer response, boolean isImmediate) {
Bitmap bitmap = response.getBitmap();
if (bitmap != null) {
//
// manipulations
//
// assuming mView is a reference to your ImageView
mView.setImageBitmap(bitmap);
} else {
// display placeholder or whatever you want
}
}
}
来自Javadoc:
呼叫流程如下:
附加到请求后,将调用onResponse(response,true)来反映任何已可用的缓存数据。如果数据可用,response.getBitmap()将为非null。
在网络响应返回后,只会发生以下情况之一:
如果加载了图像,将调用onResponse(response,false)。
或
如果加载图像时出错,将调用onErrorResponse。
目前在volution中有一个错误(我70%确信这是一个错误),如果没有指定缓存过期(比如说,如果你从S3存储桶中获得一个具有永不过期设置的图像),你总是会从网络重新下载。
您可以通过检查HttpHeaderParser并将相关位(这并不完全疯狂,因为您无论如何都必须包含截击源代码)更改为:
// Cache-Control takes precedence over an Expires header, even if both exist and Expires
// is more restrictive.
if (hasCacheControl) {
softExpire = now + maxAge * 1000;
} else if (serverDate > 0 && serverExpires >= serverDate) {
// Default semantic for Expire header in HTTP specification is softExpire.
softExpire = now + (serverExpires - serverDate);
} else if (serverExpires == 0) {
softExpire = Long.MAX_VALUE;
}
然后,您可以将Uri传递给活动,将其作为参数打开。该解决方案具有令人羡慕的特性,即如果在启动活动和显示位图之间图像出现问题,您仍然可以重新下载它,并且一切正常。这种情况可能永远不会/很少发生,但很高兴知道正确性得到了保留。