Volley cache creates duplicate views in android recycler view

Viewed 175

I am using volley cache to save data offline so the app could worok offline too. Below is my main activity.

    private void getDataFromServer() {
    //Initializing ProgressBar
    final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar1);

    //Displaying Progressbar
    progressBar.setVisibility(View.VISIBLE);
    setProgressBarIndeterminateVisibility(true);

    //JsonArrayRequest of volley
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Config.DATA_URL ,
            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    for (int i = 0; i < response.length(); i++) {
                        //Creating the superhero object

                        try {
                            //Getting json
                            Categories gradee = new Categories();
                            JSONObject json = response.getJSONObject(i);

                            //Adding data to the superhero object
                            gradee.setImageUrl(json.getString(Config.TAG_G_IMAGE_URL));
                            gradee.setName(json.getString(Config.TAG_G_NAME));
                            listGrades.add(gradee);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                       // LinkedHashSet<Categories> set = new LinkedHashSet<>(listGrades);
                       // listGrades.clear();
                       // listGrades.addAll(new ArrayList<>(set));
                    }
                    progressBar.setVisibility(View.GONE);
                    adapter.notifyDataSetChanged();
                 //   requestQueue.getCache().clear();

                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    progressBar.setVisibility(View.GONE);
                  /*  new AlertDialog.Builder(MainActivity.this)
                            .setMessage("Unable to save data from server. Check Your Internet Connection")
                            .setPositiveButton("Refresh", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    Intent i = new Intent(MainActivity.this, Splashscreen.class);
                                    startActivity(i); }
                            })
                            .show();  */
                }
            })
    {
        @Override
        protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {


            try {
                Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
                if (cacheEntry == null) {
                    cacheEntry = new Cache.Entry();
                    listGrades.clear();
                }
                final long cacheHitButRefreshed = 1 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
                final long cacheExpired = 24 * 60 * 60 * 1000; // in 48 hours this cache entry expires completely
                long now = System.currentTimeMillis();
                final long softExpire = now + cacheHitButRefreshed;
                final long ttl = now + cacheExpired;
                cacheEntry.data = response.data;
                cacheEntry.softTtl = softExpire;
                cacheEntry.ttl = ttl;
                String headerValue;
                headerValue = response.headers.get("Date");
                if (headerValue != null) {
                    cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
                }
                headerValue = response.headers.get("Last-Modified");
                if (headerValue != null) {
                    cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
                }

                cacheEntry.responseHeaders = response.headers;
                final String jsonString = new String(response.data,
                        HttpHeaderParser.parseCharset(response.headers));
                return Response.success(new JSONArray(jsonString), cacheEntry);


            } catch (UnsupportedEncodingException | JSONException e) {
                return Response.error(new ParseError(e));
            }
        }

        @Override
        protected void deliverResponse(JSONArray response) {
            super.deliverResponse(response);
        }

        @Override
        public void deliverError(VolleyError error) {
            super.deliverError(error);
        }

        @Override
        protected VolleyError parseNetworkError(VolleyError volleyError) {
            return super.parseNetworkError(volleyError);
        }
    };

  requestQueue.add(jsonArrayRequest);
}

My app displays the data in recycler view perfectly, But whenever this cacheHitButRefreshed time limit reaches, after that the app starts displaying Duplicate views. The app works fine in offline mode. Please help so i can display the data offline and online without duplicate views. I implemented it from this website : https://medium.com/android-grid/how-to-use-volley-cache-android-studio-be59cba08861 , and seems like this is also having the same issue.

I found a comment regarding this issue :

I implemented this cache system and It is working really well until today. I need to integrate pagination and when I call this request after the page is changed or the data is refreshed. Data is cached correctly and loaded correctly but after cache Hit Refresh time comes the page data again comes to the response callback. which cause It to get duplicate… I have Implemented the workaround that I filter or Distinguish data but I think that will be really expensive operation on a large.

I am uable to solve this issue, Please provide your help in solving this error.

Image

please respond guys

1 Answers

Use listGrades.clear(); before using creating the request.
I your code try before this line, JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Config.DATA_URL .
We need to clear the list we are using otherwise duplicates will occur to the list.

Related