1

与有关 Volley Image 缓存的问题有关。所以,现在我想实现 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 链接起来。

4

3 回答 3

5

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

于 2014-02-19T07:52:04.473 回答
0

我听从了 kirthika selvaraj 的建议,VolleyImageCacheExample 运行良好。我还没有深入测试它,但是当我们第二次请求相同的图像时,它可以很好地缓存图像并从缓存中加载图像。

这是我所做的:

  1. 从此链接下载示例/项目
  2. 转到 Src 文件夹,并将以下文件复制到您的项目中:RequestManager.java、DiskLruImageCache.java、ImageCacheManager.java
  3. 导入所有必要的包(如果使用 eclipse,则快捷键 Ctrl+O)
  4. 如果您仍然看到错误,可能是因为这些文件顶部的包名称。将包名称更改为您项目的包,它应该是好的。
  5. 下载 DiskLruCache.jar 文件(github 上的 jar 文件,版本可能会改变。此时,它是 DiskLruCache-2.0.2.jar)并将其添加到您的 libs 文件夹中。

以上4个步骤就完成了设置。现在需要以下步骤才能使其在您的应用程序中工作。

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

改变这个:

queue.add(jsArrayRequest);

RequestManager.getRequestQueue().add(jsArrayRequest);

3.在您的视图(列表视图/网格视图等)的适配器中getView()更改以下内容:

改变这个:

image.setImageUrl(imagepath, imageLoader);

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

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

于 2014-02-19T09:12:08.120 回答
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 没有为我们提供实现,但我们可以从这里获得一个看起来合适的实现,并根据设备规格处理缓存大小,这很酷。

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;
    }
}

如果您对如何实现这一点有更多疑问,请查看我写的这篇文章

于 2015-07-13T14:12:36.067 回答