You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何刷新Volley缓存?解决SwipeRefreshLayout无法更新JSON数据问题

解决Volley缓存与SwipeRefreshLayout刷新冲突的方案

嘿,这个问题我之前做Android项目时也踩过坑!Volley的缓存机制默认会优先读取本地缓存,除非缓存已经过期或者你明确告诉它要跳过缓存重新请求网络。针对你想要点击刷新按钮时让旧缓存失效、加载最新数据的需求,这里有几个靠谱的解决方案:

方法一:强制请求网络并自动更新缓存

这是最简洁的方案,在刷新时给Volley请求设置FORCE_NETWORK缓存策略,让它直接跳过现有缓存去请求网络,请求成功后Volley会自动把新数据写入缓存——既满足了刷新拿最新数据的需求,又不影响后续离线使用。

具体代码修改如下:

mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
    @Override
    public void onRefresh() {
        // 替换成你的JSON数据接口URL
        String requestUrl = "你的JSON数据接口地址";
        
        JsonObjectRequest refreshRequest = new JsonObjectRequest(Request.Method.GET, requestUrl, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        // 处理拿到的新数据,更新UI
                        updateYourUIWithNewData(response);
                        // 停止刷新动画
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // 处理请求错误
                        Toast.makeText(getApplicationContext(), "刷新失败,请检查网络", Toast.LENGTH_SHORT).show();
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                }) {
            // 重写getCacheControl方法,强制从网络获取数据
            @Override
            public CacheControl getCacheControl() {
                return CacheControl.FORCE_NETWORK;
            }
        };

        // 将请求加入Volley请求队列
        Volley.newRequestQueue(getApplicationContext()).add(refreshRequest);
    }
});

方法二:手动清除指定URL的缓存

如果你不想每次刷新都强制走网络,也可以在刷新时先手动清除该接口的缓存,再发起正常请求。这样Volley因为找不到缓存,就会自动去请求网络并缓存新数据。

代码示例:

mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
    @Override
    public void onRefresh() {
        String requestUrl = "你的JSON数据接口URL";
        RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
        
        // 获取Volley缓存实例,清除对应URL的缓存
        Cache cache = queue.getCache();
        cache.remove(requestUrl);

        // 发起正常的JSON请求
        JsonObjectRequest refreshRequest = new JsonObjectRequest(Request.Method.GET, requestUrl, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        updateYourUIWithNewData(response);
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(getApplicationContext(), "刷新失败,请检查网络", Toast.LENGTH_SHORT).show();
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                });

        queue.add(refreshRequest);
    }
});

补充:结合周期性缓存过期(可选)

既然你的JSON数据是按特定周期更新的,也可以给请求设置缓存过期时间,让Volley在缓存过期后自动请求新数据。不过这个更适合被动更新,用户主动刷新时还是推荐前两种方法:

@Override
public CacheControl getCacheControl() {
    // 设置缓存5分钟后过期,根据你的更新周期调整时间
    return CacheControl.Builder.newBuilder()
            .maxAge(5, TimeUnit.MINUTES)
            .build();
}

推荐优先使用方法一,因为它不需要手动操作缓存,Volley会自动处理新数据的缓存更新,代码更简洁也更符合Volley的设计逻辑。

内容的提问来源于stack exchange,提问作者Dipak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:24:47