0

I am using GridView to download data and display them on two columns. I am using Volley Library to download data. I could able to fetch and parse images and place them on the grid view, everything works.

However, when user scroll up and down, networks operation happens and reloading the images again and again. Is there a way to cache them rather to prevent download the image again and again. I am relatively newbie to Android environment.

I have implemented same feature in iOS with AFNetworking, and it works like a charm, but I am not sure what I am missing in Android platform. I thought Volley Library handles caching operation.

   <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:background="#ffffff">

    <GridView
        android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:verticalSpacing="2dp"
        android:horizontalSpacing="2dp"
        android:stretchMode="columnWidth"
        android:numColumns="2"/>

        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

</RelativeLayout>

MainActivity

JsonArrayRequest request = new JsonArrayRequest(Config.PRODUCT_URL,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                            try {
                                List<ImageRecord> imageRecords=parse(response);
                                mAdapter.swapImageRecords(imageRecords);

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        Log.d("Unable to fecth","yes");
                    }
                });
        CustomVolleyRequest.getInstance(this).getRequestQueue().add(request);

I have the following Singleton Class.

  public class CustomVolleyRequest {

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


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

        imageLoader = new ImageLoader(requestQueue,
                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 CustomVolleyRequest getInstance(Context context) {
        if (customVolleyRequest == null) {
            customVolleyRequest = new CustomVolleyRequest(context);
        }
        return customVolleyRequest;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            Cache cache = new DiskBasedCache(context.getCacheDir(), 10 * 1024 * 1024);
            Network network = new BasicNetwork(new HurlStack());
            requestQueue = new RequestQueue(cache, network);
            requestQueue.start();
        }
        return requestQueue;
    }

    public ImageLoader getImageLoader() {
        return imageLoader;
    }
}

grid_item.XML

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/picture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"
        android:layout_gravity="bottom"
        android:textColor="@android:color/white"
        android:background="#55000000"/>

</FrameLayout>

ProductMainAdapter.XML

public class ProductMainAdapter extends ArrayAdapter<ImageRecord> {
    private ImageLoader mImageLoader;
    private RequestQueue mRequestQueue;

    public ProductMainAdapter(Context context) {
        super(context, R.layout.grid_item);
        mRequestQueue = Volley.newRequestQueue(context);
        mImageLoader = new ImageLoader(mRequestQueue, 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);
            }
        });
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.grid_item, parent, false);
        }

        NetworkImageView imageView = (NetworkImageView) convertView.findViewById(R.id.picture);
        TextView textView = (TextView) convertView.findViewById(R.id.text);

        ImageRecord imageRecord = getItem(position);

        imageView.setImageUrl(imageRecord.getUrl(),mImageLoader);
        textView.setText(imageRecord.getTitle());

        return convertView;
    }
    public void swapImageRecords(List<ImageRecord> objects) {
        clear();

        for(ImageRecord object : objects) {
            add(object);
        }

        notifyDataSetChanged();
    }
}
casillas
  • 16,351
  • 19
  • 115
  • 215
  • Possible duplicate of [Volley Image Caching](http://stackoverflow.com/questions/21848749/volley-image-caching) – Ziem Dec 04 '15 at 21:33

1 Answers1

0

There is a Library Called Picasso, which will allow you to cache Images to android device. One more beauty of it is, When you use it with listview or gridview, it will handle, downloading and stopping of caching process itself. Let's take an listview adapter for example, if you are about to use Picasso to display images to a listview , the caching and cancellation of caching when the list child is visible or Invisible is handled automatically by Picasso. http://square.github.io/picasso/

I have written an article on it here

hope it helps.

HourGlass
  • 1,805
  • 1
  • 15
  • 29