2016-04-29 4 views
0

Ich habe eine Website, die Nachrichten täglich veröffentlicht.Probleme mit Volley Caching-Mechanismus

Jetzt sende ich eine JsonArrayRequest, um den Titel und die Zusammenfassung der auf der Website veröffentlichten Nachrichten abzurufen und zu analysieren. Die geparsten Elemente werden dann verwendet, um RecyclerView zu füllen.

Das Problem, das ich habe, ist die Art, wie Volley Caching implementiert.

Nehmen wir dieses Szenario: Die App ist installiert, gestartet und der RecyclerView ist ausgefüllt. Der Benutzer liest die Nachrichten und vergisst die App

Später startet der Benutzer die App und die Elemente werden abgerufen und RecyclerView wird aufgefüllt.

Zwischen dem ersten und dem zweiten Start werden neue Nachrichten auf der Website veröffentlicht. Beim zweiten Start werden diese neuen Elemente jedoch nicht angezeigt. Wenn der Benutzer jedoch manuell zu den App-Einstellungen wechselt und den Cache der App löscht und neu startet, werden die neuen Elemente angezeigt.

Sie bekommen meinen Punkt?

Während ich das Volley-Caching nicht deaktivieren möchte, wie schaffe ich es immer, neue Elemente zu holen?

EDIT

MainActivity

public class MainActivity extends AppCompatActivity { 

    private final String TAG = "MainActivity"; 



    //Creating a list of newss 
    private List<NewsItems> mNewsItemsList; 

    //Creating Views 
    private RecyclerView recyclerView; 
    private RecyclerView.Adapter adapter; 
    private RecyclerView.LayoutManager layoutManager; 
    private ProgressDialog mProgressDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Log.d(TAG, "onCreate called"); 

     //Initializing Views 
     recyclerView = (RecyclerView) findViewById(R.id.news_recycler); 
     LinearLayoutManager layoutManager = new LinearLayoutManager(this); 
     recyclerView.setLayoutManager(layoutManager); 


     //Initializing the newslist 
     mNewsItemsList = new ArrayList<>(); 
     adapter = new NewsAdapter(mNewsItemsList, this); 

     recyclerView.setAdapter(adapter); 

     if (NetworkCheck.isAvailableAndConnected(this)) { 

      //Calling method to get data 
      getData(); 
     } else { 
      //Codes for building Alert Dialog 
      alertDialogBuilder.setPositiveButton(R.string.alert_retry, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        if (!NetworkCheck.isAvailableAndConnected(mContext)) { 
         alertDialogBuilder.show(); 
        } else { 
         getData(); 
        } 

       } 
      }); 
      alertDialogBuilder.setNegativeButton(R.string.alert_cancel, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        finish(); 

       } 
      }); 
      alertDialogBuilder.show(); 

     } 


    } 



    //This method will get data from the web api 
    private void getData(){ 


     Log.d(TAG, "getData called"); 
     //Codes for Showing progress dialog 

     //Creating a json request 
     JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigNews.GET_URL + getNumber(), 
       new Response.Listener<JSONArray>() { 
        @Override 
        public void onResponse(JSONArray response) { 
         Log.d(TAG, "onResponse called"); 
         //Dismissing the progress dialog 
         if (mProgressDialog != null) { 
          mProgressDialog.hide(); 
         } 
        //calling method to parse json array 
         parseData(response); 

        } 
       }, 
       new Response.ErrorListener() { 
        @Override 
        public void onErrorResponse(VolleyError error) { 

        } 
       }); 

     //Creating request queue 
     RequestQueue requestQueue = Volley.newRequestQueue(this); 

     //Adding request to the queue 
     requestQueue.add(jsonArrayRequest); 

    } 

    //This method will parse json data 
    private void parseData(JSONArray array){ 
     Log.d(TAG, "Parsing array"); 

     for(int i = 0; i<array.length(); i++) { 
      NewsItems newsItem = new NewsItems(); 
      JSONObject jsonObject = null; 
      try { 
       jsonObject = array.getJSONObject(i); 
       newsItem.setNews_title(jsonObject.getString(ConfigNews.TAG_VIDEO_TITLE)); 
       newsItem.setNews_body(jsonObject.getString(ConfigNews.TAG_VIDEO_BODY)); 

      } catch (JSONException w) { 
       w.printStackTrace(); 
      } 
      mNewsItemsList.add(newsItem); 


     } 

     adapter.notifyItemRangeChanged(0, adapter.getItemCount()); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d(TAG, "onDestroy called"); 
     if (mProgressDialog != null){ 
      mProgressDialog.dismiss(); 
      Log.d(TAG, "mProgress dialog dismissed"); 

     } 
    } 

} 
+0

nennt So verwenden Sie ein DiskBasedCache richtig? – Krish

+0

@Krish: Weiß nicht, ich habe selbst nie Caching implementiert. Das Zwischenspeichern ist Standard. – X09

+0

Post einige Codes – Krish

Antwort

1

Option 1) Cache löschen

, bevor Sie einen Anruf tätigen können Sie den gesamten Cache von myDiskBasedCache.clear() oder bestimmte Einträge von myDiskBasedCache.remove(entryUrl) löschen

Option 2) Individueller CacheParser (in der Anfrage)

@Override 
protected Response<Bitmap> parseNetworkResponse(NetworkResponse response) { 
    Response<Bitmap> resp = super.parseNetworkResponse(response); 
    if(!resp.isSuccess()) { 
     return resp; 
    } 
    long now = System.currentTimeMillis(); 
    Cache.Entry entry = resp.cacheEntry; 
    if(entry == null) { 

     entry = new Cache.Entry(); 
     entry.data = response.data; 
     entry.responseHeaders = response.headers; 
     entry.ttl = now + 60 * 60 * 1000; //keeps cache for 1 hr 
    } 
    entry.softTtl = 0; // will always refresh 

    return Response.success(resp.result, entry); 
} 

Option 3) Anfragen senden, die nicht

myRequest.setShouldCache(false); 

Option 4) Cache verwenden, um benutzerdefinierte Implementierung

zwischenspeichert

UPDATE:

Beispiel mit Ihrem Code:

//Creating a json request 
     JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigNews.GET_URL + getNumber(), 
       new Response.Listener<JSONArray>() { 
        @Override 
        public void onResponse(JSONArray response) { 
         Log.d(TAG, "onResponse called"); 
         //Dismissing the progress dialog 
         if (mProgressDialog != null) { 
          mProgressDialog.hide(); 
         } 
        //calling method to parse json array 
         parseData(response); 

        } 
       }, 
       new Response.ErrorListener() { 
        @Override 
        public void onErrorResponse(VolleyError error) { 

        } 
       }) { 
@Override 
    protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) { 
     Response<JSONArray> resp = super.parseNetworkResponse(response); 
     if(!resp.isSuccess()) { 
      return resp; 
     } 
     long now = System.currentTimeMillis(); 
     Cache.Entry entry = resp.cacheEntry; 
     if(entry == null) { 

      entry = new Cache.Entry(); 
      entry.data = response.data; 
      entry.responseHeaders = response.headers; 
      entry.ttl = now + 60 * 60 * 1000; //keeps cache for 1 hr 
     } 
     entry.softTtl = 0; // will always refresh 

     return Response.success(resp.result, entry); 
    } 
}; 

UPDATE 2

Http-Protokoll-Caching unterstützt viele Möglichkeiten, zu definieren, wie die Client-Antworten zwischenspeichern können und wenn sie zu aktualisieren. Volley vereinfacht diese Regeln auf:

  • Eintrag.ttl (Zeit in ms zu leben), wenn mehr als die aktuelle Zeit dann kann Cache sonst frisch Anforderung verwendet werden muss, um

und

  • entry.softTtl (soft Zeit gemacht werden leben in ms :) wenn größer als die aktuelle Zeit Cache ist absolut gültig und keine Anfrage an den Server muss gemacht werden, sonst wird eine neue Anfrage immer noch gemacht (auch wenn die ttl ist gut) und wenn es eine Änderung gibt neue Antwort wird wird geliefert.

    beachten Sie, dass, wenn ttl gültig ist und softTtl ist nicht Sie 2 empfangen kann onResponse

+0

Das wird den Cache löschen, oder? Gibt es keinen anderen Weg? – X09

+0

Nun können Sie einen benutzerdefinierten Cacheparser haben – djodjo

+0

Oder was, wenn ich Datenträgercache deaktivieren und Speichercache aktivieren? Ist das möglich? – X09