Я использую Volley
сетевую библиотеку в Android
для REST API
. И я использую залповый кеш для автономного ответа , но у меня возникают некоторые проблемы с кешем. Когда моя мобильная сеть отключена, это работает нормально, но если в сети залп дает двойной ответ .
- Из кеша
- С сервера
Но я хочу получить ответ от сервера if the network is online
и от кэша if the network is offline
.
Это мой пользовательский запрос:
public class CustomRequest extends Request<JSONObject> {
public static final int MY_SOCKET_TIMEOUT_MS = 60000;
private Response.Listener<JSONObject> listener;
private Map<String, String> params;
JSONObject jsonBody;
private boolean isRequiredCache = false;
public CustomRequest(String url, Map<String, String> params,
Response.Listener<JSONObject> reposeListener, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reposeListener;
this.params = params;
}
public CustomRequest(int method, String url, Map<String, String> params,
Response.Listener<JSONObject> reposeListener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reposeListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
}
public void setRequiredCache(boolean requiredCache) {
isRequiredCache = requiredCache;
}
@Override
public byte[] getBody() throws AuthFailureError {
if (params != null) {
JSONObject obj = new JSONObject(params);
return obj.toString().getBytes();
}
else
{
return null;
}
}
@Override
public Request<?> setRetryPolicy(RetryPolicy retryPolicy) {
if (getMethod() == Method.POST || getMethod() == Method.PUT) {
retryPolicy = new DefaultRetryPolicy(MY_SOCKET_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
}
return super.setRetryPolicy(retryPolicy);
}
@Override
public String getBodyContentType() {
return "application/json";
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
if (isRequiredCache) {
return Response.success(new JSONObject(jsonString),
parseIgnoreCacheHeaders(response));
} else {
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
}
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
@Override
protected void deliverResponse(JSONObject response) {
// TODO Auto-generated method stub
listener.onResponse(response);
}
/**
* Extracts a {@link Cache.Entry} from a {@link NetworkResponse}.
* Cache-control headers are ignored. SoftTtl == 3 mins, ttl == 24 hours.
* @param response The network response to parse headers from
* @return a cache entry for the given response, or null if the response is not cacheable.
*/
public static Cache.Entry parseIgnoreCacheHeaders(NetworkResponse response) {
long now = System.currentTimeMillis();
Map<String, String> headers = response.headers;
long serverDate = 0;
String serverEtag = null;
String headerValue;
headerValue = headers.get("Date");
if (headerValue != null) {
serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
serverEtag = headers.get("ETag");
final long cacheHitButRefreshed = 0; // 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
final long softExpire = now + cacheHitButRefreshed;
final long ttl = now + cacheExpired;
Cache.Entry entry = new Cache.Entry();
entry.data = response.data;
entry.etag = serverEtag;
entry.softTtl = softExpire;
entry.ttl = ttl;
entry.serverDate = serverDate;
entry.responseHeaders = headers;
return entry;
}
}