Volley StringRequest首次请求后不调用getParams,需保缓存且每次传POST参数
解决Volley POST分页请求动态参数与缓存共存的问题
我太懂你这个困扰了——Volley默认靠URL生成缓存Key,导致带不同分页参数的POST请求会被当成同一个,直接复用旧缓存跳过getParams();但要是直接禁用缓存或者清缓存,又浪费了Volley自带的缓存优势,对分页加载这种场景太不友好了。
核心解决思路是让缓存Key包含POST参数,这样不同参数的请求会生成独立的缓存条目,既保证每次都能拿到动态变化的分页参数,又能正常缓存对应页的响应结果。
具体实现方案
- 继承
StringRequest重写getCacheKey()方法,把getParams()返回的参数拼接进缓存Key,确保不同参数的请求有唯一标识 - 不需要调用
setShouldCache(false)或clearCache(),完全保留Volley默认的缓存逻辑
修改后的完整代码
// 自定义支持参数缓存Key的StringRequest class ParamAwareStringRequest extends StringRequest { public ParamAwareStringRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { super(method, url, listener, errorListener); } @Override public String getCacheKey() { try { // 获取POST参数并拼接成缓存Key的一部分 Map<String, String> params = getParams(); StringBuilder keyBuilder = new StringBuilder(super.getCacheKey()); for (Map.Entry<String, String> entry : params.entrySet()) { keyBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue()); } return keyBuilder.toString(); } catch (AuthFailureError authFailureError) { authFailureError.printStackTrace(); // 兜底:获取参数失败时用默认URL作为缓存Key return super.getCacheKey(); } } } // 使用自定义Request发起分页请求 ParamAwareStringRequest stringRequest = new ParamAwareStringRequest(Request.Method.POST, url, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.e("RES", response); GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setDateFormat("M/d/yy hh:mm a"); Gson gson = gsonBuilder.create(); NewsFeedPOJO resultObj = gson.fromJson(response, NewsFeedPOJO.class); inCurrPage = Integer.parseInt(resultObj.getPagination().getCurrent_page()); inTotalPage = Integer.parseInt(resultObj.getPagination().getTotal_pages()); inCurrPage++; arrayList.addAll(resultObj.getNewsFeedList()); if (isFtym) { isFtym = false; layoutManager = new LinearLayoutManager(MainActivity.this); rcNewsFeed.setLayoutManager(layoutManager); adapter = new NewsFeedAdapter(MainActivity.this, arrayList); rcNewsFeed.setAdapter(adapter); } else { adapter.notifyItemInserted(arrayList.size()); adapter.notifyDataSetChanged(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // 这里可以补充错误提示逻辑 } }) { @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> map = new HashMap<>(); map.put("user_id", "188"); map.put("page", inCurrPage == 0 ? "1" : String.valueOf(inCurrPage)); Log.e("RES", inCurrPage + " PARA"); return map; } }; // 直接加入请求队列即可,无需额外禁用缓存或清缓存操作 VolleySingleton.getInstance(this).addToRequestQueue(stringRequest);
原理说明
- Volley默认的
getCacheKey()只返回请求URL,所以带不同page参数的POST请求会被判定为同一个请求,直接返回旧缓存,不会触发getParams() - 自定义的
ParamAwareStringRequest把POST参数拼接到缓存Key中,比如page=1和page=2会生成不同的Key,Volley会把它们当成独立请求,每次都会调用getParams()获取最新参数,同时缓存对应页的响应 - 这种方式完全保留了Volley的缓存机制,当再次请求同一页时,会直接返回缓存结果,提升加载速度
内容的提问来源于stack exchange,提问作者Goku
相关产品推荐
相关产品推荐

