Volley库响应重复接收及GET请求次数异常问题排查求助
Volley重复请求/响应重复显示问题排查与修复
问题根源分析
你的代码存在两个核心问题,直接导致了请求重复发送和响应数据重复显示:
- RequestQueue重复实例化
每次调用getOutputFromDatabase方法时,都新建了一个RequestQueue实例:
mRequestQueue = Volley.newRequestQueue(this);
Volley的RequestQueue是设计为单例复用的,多次创建会导致多个请求分发线程池同时工作,引发请求被重复提交或响应被重复处理的问题。
- JSON解析逻辑硬编码错误
无论当前请求的是收入、支出、储蓄还是食品数据,代码都固定解析"Total income"字段:
JSONArray recs = locs.getJSONArray("Total income");
这意味着所有请求的响应都会被当作收入数据处理,进而重复向饼图添加收入切片,造成数据重复显示的假象。
修复方案
1. 复用RequestQueue单例
在Activity的onCreate中仅初始化一次RequestQueue,后续所有请求复用该实例:
private RequestQueue mRequestQueue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout); // 仅初始化一次RequestQueue mRequestQueue = Volley.newRequestQueue(this); // 初始化请求 initialize(); }
然后修改getOutputFromDatabase方法,移除重复创建RequestQueue的代码,直接使用已初始化的实例:
private void getOutputFromDatabase(String type) { // 移除 mRequestQueue = Volley.newRequestQueue(this); 这一行 // 剩余URL构建逻辑不变... // 请求添加到已有的RequestQueue mRequestQueue.add(mStringRequest); }
2. 动态匹配JSON解析字段
根据请求类型动态获取对应的JSON字段,避免硬编码:
@Override public void onResponse(String response) { try { JSONObject obj = new JSONObject(response); JSONObject locs = obj.getJSONObject("incomeexpense"); // 根据请求类型确定要解析的字段、饼图配置和目标TextView String targetField = ""; String pieLabel = ""; int pieColor = 0; TextView targetTextView = null; switch (type) { case "income": targetField = "Total income"; pieLabel = "Total income"; pieColor = Color.parseColor("#99CC00"); targetTextView = totalIncome; break; case "expense": targetField = "Total expense"; // 需与接口返回的支出字段名一致 pieLabel = "Total spending"; pieColor = Color.parseColor("#FF4444"); targetTextView = totalExpense; break; case "savings": targetField = "Total savings"; pieLabel = "Total savings"; pieColor = Color.parseColor("#33B5E5"); targetTextView = totalSavings; break; case "food": targetField = "Food/day"; // 需与接口返回的食品字段名一致 pieLabel = "Food/day"; pieColor = Color.parseColor("#FFBB33"); targetTextView = totalFood; break; } JSONArray recs = locs.getJSONArray(targetField); String repl = recs.getString(0); if ("null".equals(repl)) { targetTextView.setText("0"); } else { targetTextView.setText(repl); pieChart.addPieSlice(new PieModel(pieLabel, Float.parseFloat(repl), pieColor)); // 所有请求完成后再执行动画,避免提前触发(可根据实际情况调整触发时机) pieChart.startAnimation(); } } catch (JSONException e) { e.printStackTrace(); } }
3. 额外优化:避免动画重复触发
可以将pieChart.startAnimation()移到所有请求完成后的统一回调中,或者在每个请求的onResponse里判断是否是最后一个请求,避免多次触发动画。
内容的提问来源于stack exchange,提问作者Bernd
相关产品推荐
相关产品推荐

