JakeWharton DiskLruCache - 如何用Volley实现?

时间:2014-02-19 05:40:55

标签: android android-volley image-caching

这与关于Volley Image缓存的this问题有关。所以,现在我想实现DiskLruCache,但我不知道如何做到这一点。

我从github下载了Jar文件并将其添加到我的项目中。

接下来我该怎么办?如何更改Volley的现有代码并集成DiskLruCache?

现有代码:

初始化排球:

queue = Volley.newRequestQueue(getActivity());
imageLoader = new ImageLoader(queue, new ImageLoader.ImageCache() {
    private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(
            10);

    public void putBitmap(String url, Bitmap bitmap) {
        mCache.put(url, bitmap);
    }

    public Bitmap getBitmap(String url) {
        return mCache.get(url);
    }
});

从服务器获取响应并解析:

jsArrayRequest = new JsonArrayRequest(url,
        new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {
                if (Const.DEBUGGING) {
                    Log.d(Const.DEBUG,
                            "Response => " + response.toString());
                    Log.d(Const.DEBUG, "Length = " + response.length());
                }
                parseResponse(response, url);

                setRetrivalSuccess();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (Const.DEBUGGING) {
                    Log.d(Const.DEBUG, "Volley Error");
                    Log.d(Const.DEBUG, "Error = " + error.toString());
                }

                ((MainFragmentActivity) getActivity())
                        .setSupportProgressBarIndeterminateVisibility(false);

            }
        });
queue.add(jsArrayRequest);

我在SO上看到了一些例子,但我无法理解如何将Volley与DiskLruCache联系起来。

3 个答案:

答案 0 :(得分:5)

ImageLoader需要一个ImageCache,要使用DiskLruCache,你必须有一个包装器来实现ImageCache。 VolleyImageCacheExample(推荐的方法是使用基本内存LRU缓存作为L1缓存,将磁盘缓存作为L2)

答案 1 :(得分:0)

我遵循了kirthika selvaraj的建议,而VolleyImageCacheExample运作良好。我没有深入测试它,但是当我们第二次请求相同的图像时,它正好缓存图像并从缓存加载图像。

这就是我所做的:

  1. 从此link
  2. 下载示例/项目
  3. 转到Src文件夹,将以下文件复制到项目中:RequestManager.java,DiskLruImageCache.java,ImageCacheManager.java
  4. 导入所有必需的软件包(如果使用eclipse,则快捷键Ctrl + O)
  5. 如果仍然看到错误,可能是因为这些文件顶部的包名称。将包名更改为项目的包,它应该是好的。
  6. 下载DiskLruCache.jar文件(github上可用的jar文件,版本可能会更改。此时,它是DiskLruCache-2.0.2.jar)并将其添加到您的libs文件夹中。
  7. 以上4个步骤完成了设置。现在需要以下步骤才能使其在您的应用程序中运行。

    1. 如果您有应用文件,请将示例中的MainApplication.java代码添加到您的应用文件中。如果没有,您可以直接将MainApplication.java添加到您的项目中。
    2. 将请求对象的添加位置更改为RequestQueue,如下所示:
    3. 改变这个:

      queue.add(jsArrayRequest);
      

      RequestManager.getRequestQueue().add(jsArrayRequest);
      

      3.在getView()的视图适配器(listview / gridview等)中更改以下内容:

      改变这个:

      image.setImageUrl(imagepath, imageLoader);
      

      image.setImageUrl(imagepath, ImageCacheManager.getInstance()
                          .getImageLoader());
      

      这应该可以使它工作。如果您有任何问题,请告诉我。

答案 2 :(得分:0)

整个应用程序只使用一个队列作为单例。

    /**
     * Returns an image loader instance to be used with Volley.
     *
     * @return {@link com.android.volley.toolbox.ImageLoader}
     */
    public ImageLoader getVolleyImageLoader()
    {
        if (mImageLoader == null)
        {
            mImageLoader = new ImageLoader
                    (
                            getVolleyRequestQueue(),
                            App.getInstance().getVolleyImageCache()
                    );
        }

        return mImageLoader;
    }

    /**
     * Returns a Volley request queue for creating network requests
     * @return {@link com.android.volley.RequestQueue}
     */
    public RequestQueue getVolleyRequestQueue()
    {
        if (mRequestQueue == null)
        {
            mRequestQueue = Volley.newRequestQueue(this, new OkHttpStack(new OkHttpClient()));
        }
        return mRequestQueue;
    }

    /**
     * Returns a bitmap cache to use with volley.
     *
     * @return {@link LruBitmapCache}
     */
    private LruBitmapCache getVolleyImageCache()
    {
        if (mLruBitmapCache == null)
        {
            mLruBitmapCache = new LruBitmapCache(mInstance);
        }
        return mLruBitmapCache;
    }

Volley没有为我们提供一个实现,但we can get one from here看起来合适并处理每个设备规格的缓存大小,这很酷。

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.util.DisplayMetrics;
import com.android.volley.toolbox.ImageLoader.ImageCache;

public class LruBitmapCache extends LruCache<String, Bitmap>
        implements ImageCache {

    public LruBitmapCache(int maxSize) {
        super(maxSize);
    }

    public LruBitmapCache(Context ctx) {
        this(getCacheSize(ctx));
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight();
    }

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

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

    // Returns a cache size equal to approximately three screens worth of images.
    public static int getCacheSize(Context ctx) {
        final DisplayMetrics displayMetrics = ctx.getResources().
                getDisplayMetrics();
        final int screenWidth = displayMetrics.widthPixels;
        final int screenHeight = displayMetrics.heightPixels;
        // 4 bytes per pixel
        final int screenBytes = screenWidth * screenHeight * 4;

        return screenBytes * 3;
    }
}

如果您对如何实施此问题有更多疑问,请查看this article that I've written about it