0

I am trying to understand Volley's image caching. I have a fragment with network image view, which will load an image from the server. I am not able to display the image using NetworkImageView, when i try to load an image nothing shows up. I read Volley automatically takes care of Image Caching. But I think I may not be using a proper way to load image from the server.

Below is my code:

Volley Singleton Class

public class Volley {
    private static Volley mInstance;
    private static Context mContext;

    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;

    private Volley(Context context) {
        mContext = context;
        mRequestQueue = getRequestQueue();
        ImageLoader.ImageCache imageCache = new BitmapLruCache();
//        ImageLoader imageLoader = new ImageLoader(Volley.newRequestQueue(context), imageCache);
        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
                    private final LruCache<String, Bitmap>
                            cache = new LruCache<String, Bitmap>(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 Volley getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new Volley(context);
        }

        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = com.android.volley.toolbox.Volley.newRequestQueue(mContext.getApplicationContext());
        }

        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public  ImageLoader getImageLoader() {
        return mImageLoader;
    }
}

I have initialized network image view in my fragment:

        String url =  "https://pixabay.com/en/youtube-laptop-notebook-online-1158693/";
        mImageView = ((NetworkImageView) mView.findViewById(R.id.imageView));
        ImageLoader imageLoader = Volley.getInstance(mContext).getImageLoader();
        mImageView.setImageUrl(url, imageLoader);

LruCache class

public class BitmapLruCache extends LruCache<String, Bitmap>
        implements ImageLoader.ImageCache {
    public BitmapLruCache() {
        this(getDefaultLruCacheSize());
    }

    public BitmapLruCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

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

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

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

    public static int getDefaultLruCacheSize() {
        final int maxMemory =
                (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }
}

I have read alot of articles and official google documentation but i don't understand how will it work in my case.

Thanks in advance

  • You are missing `imageLoader.get()` call. – Abbas Feb 22 '17 at 13:07
  • 1
    I would highly recommend using some existing image loading and caching library, such as Picasso or Fresco. There is no point in implementing these things yourself when you have an option to use something that is actively maintained and optimized, and does the same thing in a few lines of code. – Juuso Feb 22 '17 at 13:25

1 Answers1

1

You are missing get call for ImageLoader. You also might want to set your image in the response call back.

imageLoader.get(url, new ImageLoader.ImageListener() {
    @Override
    public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
        mImageView.setImage(response.getBitmap());
    }

    @Override
    public void onErrorResponse(VolleyError error) {

    }
});

I've not checked the code in a compiler so there might be some errors in the code. And do consider @Juuso Lappalainen's comment, Picasso is a very nice library for image loading and automatic caching, where you only need to specify size of cache. And loading of image can be simplified to a single line.

Abbas
  • 3,529
  • 5
  • 36
  • 64
  • 1
    Let me tell you how StackOverflow works: when someone asks a question they also mark one answer as accepted (which means that answer resolved the issue), If you like an answer and think it contains complete, concise and well-stated information then Up-Vote that answer. So If my answer solved your issue then please mark it as accepted. – Abbas Feb 22 '17 at 16:13