Android拉取服务端JSON更新后不显示,清缓存才生效如何解决
解决方案
核心问题原因
- Volley默认开启HTTP响应缓存,未配置的情况下会优先返回缓存的旧数据,不会请求服务端最新内容
- 每次拉取数据前未清空原有列表缓存,即便拿到新数据也会和旧数据叠加而非替换
- 布局内置的下拉刷新组件未绑定逻辑,无法手动触发数据更新
- Glide图片加载默认开启缓存,若服务端图片资源更新但链接不变,会继续展示旧图片
具体修改步骤
1. 配置Volley强制拉取最新数据,每次请求清空旧列表
首先在Home类中把Adapter和SwipeRefreshLayout声明为全局变量,修改请求逻辑关闭缓存、清空旧数据:
public class Home extends Fragment { private final String JSON_URL = "https://mywebsite.org/news/api.php"; private JsonArrayRequest request ; private RequestQueue requestQueue ; private List<Anime> lstAnime ; private RecyclerView recyclerView ; ProgressBar loading; // 新增全局变量 private RecyclerViewAdapter myadapter; private SwipeRefreshLayout swipeContainer; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_home, container, false); loading = root.findViewById(R.id.bar); loading.setMax(100); lstAnime = new ArrayList<>() ; recyclerView = root.findViewById(R.id.recyclerviewid); // 绑定下拉刷新组件 swipeContainer = root.findViewById(R.id.swipeContainer); // 初始化RecyclerView和Adapter,只做一次 initRecyclerView(); // 绑定下拉刷新监听 swipeContainer.setOnRefreshListener(() -> { jsonrequest(); }); // 设置刷新动画配色可选 swipeContainer.setColorSchemeResources(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light); jsonrequest(); return root; } // 新增初始化RecyclerView方法,只调用一次 private void initRecyclerView(){ myadapter = new RecyclerViewAdapter(getActivity(),lstAnime); GridLayoutManager manager = new GridLayoutManager(getActivity(), 2); manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { if (position == 0 || position == 9) { return 2; } return 1;} }); recyclerView.setItemAnimator(null); recyclerView.setHasFixedSize(true); recyclerView.setAdapter(myadapter); recyclerView.setLayoutManager(manager); } private void jsonrequest() { // 请求前先清空旧数据 lstAnime.clear(); request = new JsonArrayRequest(JSON_URL, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { loading.setVisibility(View.GONE); // 关闭下拉刷新动画 if(swipeContainer.isRefreshing()){ swipeContainer.setRefreshing(false); } JSONObject jsonObject = null ; for (int i = 0 ; i < response.length(); i++ ) { try { jsonObject = response.getJSONObject(i) ; Anime anime = new Anime() ; anime.setName(jsonObject.getString("title")); anime.setDescription(jsonObject.getString("description")); anime.setDate(jsonObject.getString("date")); anime.setCategorie(jsonObject.getString("category")); anime.setAuthor(jsonObject.getString("admin")); anime.setImage_url(jsonObject.getString("thumbnail")); lstAnime.add(anime); } catch (JSONException e) { e.printStackTrace(); } } // 通知Adapter数据更新 myadapter.notifyDataSetChanged(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // 错误时也要关闭刷新动画 loading.setVisibility(View.GONE); if(swipeContainer.isRefreshing()){ swipeContainer.setRefreshing(false); } if (error instanceof TimeoutError || error instanceof NoConnectionError) { Toast.makeText(getActivity(), "超时,请检查网络连接", Toast.LENGTH_LONG).show(); } else if (error instanceof AuthFailureError) { Toast.makeText(getActivity(), "获取数据失败", Toast.LENGTH_LONG).show(); } else if (error instanceof ServerError) { Toast.makeText(getActivity(), "服务器维护中", Toast.LENGTH_LONG).show(); } else if (error instanceof NetworkError) { Toast.makeText(getActivity(), "网络无响应", Toast.LENGTH_LONG).show(); } else if (error instanceof ParseError) { Toast.makeText(getActivity(), "请重新加载", Toast.LENGTH_LONG).show(); } } }); // 核心配置:关闭Volley缓存,强制拉取服务端最新数据 request.setShouldCache(false); requestQueue = Volley.newRequestQueue(getActivity()); requestQueue.add(request); } // 其余原有代码保持不变 }
2. 配置Glide缓存策略适配图片更新
如果服务端图片资源更新但链接不变,可修改RecyclerViewAdapter中Glide的加载配置,跳过缓存(如果图片链接会随资源更新而变化则不需要改):
// 替换原有的Glide加载代码 Glide.with(mContext) .load(mData.get(position).getImage_url()) .apply(option) .skipMemoryCache(true) // 跳过内存缓存 .diskCacheStrategy(DiskCacheStrategy.NONE) // 跳过磁盘缓存 .into(holder.thumbnail);
如果不想完全禁用缓存影响性能,可在服务端返回的图片数据中新增版本号参数,每次图片更新时修改版本号,Glide会自动识别为新资源加载。
3. 可选:实现自动定时刷新
如果需要不需要手动操作的实时更新,可在Fragment可见时开启定时任务,每隔固定时间(比如5分钟)自动调用jsonrequest()拉取最新数据,Fragment不可见时关闭定时任务避免浪费资源。
内容的提问来源于stack exchange,提问作者Litu
相关产品推荐
相关产品推荐

