【发布时间】:2020-11-28 21:25:39
【问题描述】:
我正在使用 volley 缓存离线保存数据,因此该应用程序也可以离线工作。以下是我的主要活动。
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);
}
我的应用程序完美地在回收器视图中显示数据,但是每当达到这个 cacheHitButRefreshed 时间限制时,应用程序就会开始显示重复视图。该应用程序在离线模式下运行良好。请帮助,以便我可以离线和在线显示数据而不会重复查看。我从这个网站实现了它:https://medium.com/android-grid/how-to-use-volley-cache-android-studio-be59cba08861,似乎这也有同样的问题。
我找到了关于这个问题的评论:
我实现了这个缓存系统,直到今天它运行良好。我需要集成分页,当我在页面更改或数据刷新后调用此请求时。数据被正确缓存并正确加载,但在缓存命中刷新时间到来之后,页面数据再次进入响应回调。这导致它得到重复...... 我已经实施了过滤或区分数据的解决方法,但我认为这将是一个非常昂贵的大型操作。
我无法解决此问题,请提供您的帮助以解决此错误。
请大家回复
【问题讨论】:
-
谁能帮我解决这个问题
-
可能问题出在更新 listGrades.add(gradee) 并最终执行 adapter.notifyDataSetChanged() 时。可能是 listGrades 有以前的数据,并且您将相同的数据添加到列表中,所以结果是重复的...尝试在更新它之前清除您的 listGrades。如果这个解决方案不可能,在更新列表之前,检查对象是否在列表中,如果对象不在列表中,则更新列表并最终通知适配器的更改。
-
@ManuelMato 我发现了问题,它在 cacheHitButRefreshed 中,每当它刷新缓存数据时,我都会得到重复的响应。但我不知道如何解决这个错误。请帮忙
-
尝试在 cacheHitButRefreshed 方法之前清空 listgrades。这将初始化 listgrades,因此每当调用 cacheHitButRefreshed 时,都会再次添加整个列表元素。
-
@JalakamKiran 你能写出正确的答案吗?没看懂
标签: java android android-studio android-recyclerview android-volley