如何使用Volley缓存要在Another Activity中使用的NetworkImage

时间:2017-01-19 04:10:30

标签: android caching gridview android-volley

我有两个观点,一个是主要观点,另一个是细节。我从服务器获取所有URL并在gridview上相应地显示位图。用户点击网格项后,我想在主视图中使用缓存图像。但是,我的以下实现不起作用。

我测试的方式如下:首先,我在gridview上显示所有图像并断开Internet连接,并希望在细节上看到缓存的图像。但是,在细节活动中,图像未显示。

我使用以下 Volley Singleton 课程如下:

public class CustomVolleyRequest {

    private static CustomVolleyRequest customVolleyRequest;
    private static Context context;
    private RequestQueue requestQueue;
    private ImageLoader imageLoader;

    private CustomVolleyRequest(Context context) {
        CustomVolleyRequest.context = context;
        this.requestQueue = getRequestQueue();

        imageLoader = new ImageLoader(requestQueue,
                new ImageLoader.ImageCache() {
                    private final LruCache<String, Bitmap>
                            cache = new LruCache<>(20);

                    @Override
                    public Bitmap getBitmap(String url) {
                        return cache.get(url);
                    }

                    @Override
                    public void putBitmap(String url, Bitmap bitmap) {
                        cache.put(url, bitmap);
                    }
                });
    }

    public static synchronized CustomVolleyRequest getInstance(Context context) {
        if (customVolleyRequest == null) {
            customVolleyRequest = new CustomVolleyRequest(context);
        }
        return customVolleyRequest;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(context.getApplicationContext(), 10 * 1024 * 1024);
        }
        return requestQueue;
    }

    ImageLoader getImageLoader() {
        return imageLoader;
    }
}

主要活动适配器

public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
    final ViewHolder holder;
    if(convertView == null) {
        holder = new ViewHolder();
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.grid_item, parent, false);
    }
  holder.imageView.setImageUrl(imageRecord.getUrl(), mImageLoader);
}

详情活动

String url = getArguments().getString("image_url");
ImageLoader imageLoader = CustomVolleyRequest.getInstance(getContext()).getImageLoader();
mImageView.setImageUrl(url, imageLoader);

1 个答案:

答案 0 :(得分:0)

如果ImageView的大小不同,则图像缓存的默认实现将不起作用,因为ImageLoader传递的缓存的键包括视图的大小:

private static String getCacheKey(String url, int maxWidth, int maxHeight, ScaleType scaleType) {
    return "#W" + maxWidth + "#H" + maxHeight + "#S" + scaleType.ordinal() + url;
}

您有两个主要选择:

1)重新设计ImageLoader和NetworkImageView,因为它放置了实际转换后的位图,其大小可能不同,您可能需要调用createScaledBitmap()将其调整为视图。

2)确保缓存从网络收到的原始图像数据。

所以1)相对复杂,因为你必须更改几个类,以便在ImageRequest中完成解析,而不是缩放原始图像数据,但是在接收和缓存图像后执行缩放,基本上在NetworkImageView中或在ImageLoader的后期< / p>

如果你去2,你可能需要调整Volley的默认网络缓存实现,如果你的服务器没有发送缓存头或etag。 在这种情况下,您需要对ImageLoader进行一些更改,以便检查https://stackoverflow.com/a/36549815/2267924