Reputation:
my below sample code work fine without any some problem, this sample code can cache received data from url and using that when device doesnt have any internet connection.
but this code have a big deficiency, it is when device have internet connection i cant recache and get newest data from internet and recache again until device doesnt have connection, some data can be image
or json array
or json object
public class MainActivity extends AppCompatActivity {
private final Context mContext = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = (TextView) findViewById(R.id.textView);
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://192.168.1.2/test";
CacheRequest cacheRequest =
new CacheRequest(0, url, new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
try {
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
JSONObject jsonObject = new JSONObject(jsonString);
textView.setText(jsonObject.toString(5));
Log.e('OutPut',jsonObject.toString());
} catch (UnsupportedEncodingException | JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(mContext, "onErrorResponse:\n\n" + error.toString(), Toast.LENGTH_SHORT).show();
}
});
queue.add(cacheRequest);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class CacheRequest extends Request<NetworkResponse> {
private final Response.Listener<NetworkResponse> mListener;
private final Response.ErrorListener mErrorListener;
public CacheRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
@Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
if (cacheEntry == null) {
cacheEntry = new Cache.Entry();
}
final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 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;
return Response.success(response, cacheEntry);
}
@Override
protected void deliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
@Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return super.parseNetworkError(volleyError);
}
@Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
}
}
Upvotes: 1
Views: 2166
Reputation: 5947
You can first check your Internet connection, if you have connection you can clear the cache and reload
ConnectivityManager connMgr = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
MySocialMediaSingleton.getInstance(getContext()).getRequestQueue().getCache().invalidate("http://server/json.php?page=1", true);
}
//Calling again method to get data to fetch data
getData();
Upvotes: 0
Reputation:
It will cache only once because onCreate method is called once the app created..
most suitable solution would be this:
You need to have a Service which uses AlarmManager for, say, every 5 minutes to trigger itself. And in this service you can cache the newest data in the background, of course for smaller time unit, more battery will be consumed.
update for cache resizing
RequestQueue volleyQueue = Volley.newRequestQueue(this);
DiskBasedCache cache = new DiskBasedCache(getCacheDir(), 16 * 1024 * 1024);
volleyQueue = new RequestQueue(cache, new BasicNetwork(new HurlStack()));
volleyQueue.start();
according to that discussion volley's cache can be manipulated, but when it gets full, automatically replaces new data with the old one so, cache size is not the focus right now.
update for cache cleaning
mahdi, according to official link of google volley's Cache class, there is a method called invalidate(), which invalidates the cached data, and next time volley checks if data was valid and update it.
you can appereantly delete cache for every 30 minutes according to this discussion:
serverDate: AppController.getInstance().getRequestQueue().getCache().get(url).serverDate
getMinutesDifference is method calculates time passed, can be found on reference link.
Calendar calendar = Calendar.getInstance();
long serverDate = AppController.getInstance().getRequestQueue().getCache().get(url).serverDate;
if(getMinutesDifference(serverDate, calendar.getTimeInMillis()) >=30)
{
AppController.getInstance().getRequestQueue().getCache().invalidate(url, true);
}
Upvotes: 1