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

Picasso 2.8中如何正确失效图片URL缓存?

问题

应用使用Picasso 2.8加载头像,核心代码如下:

Picasso.get()
    .load(Constant.getInstance().MERCHANT.getProfPic())
    .resize(width, width)
    .centerInside()
    .placeholder(R.drawable.avatar)
    .error(R.drawable.avatar)
    .into(profPicView);

问题点:Constant.getInstance().MERCHANT.getProfPic()的URL固定不变,但图片内容已更新,Picasso基于URL缓存的机制导致始终显示旧头像。尝试过以下方法均未解决:

  1. 头像上传成功后调用Picasso.get().invalidate(...)清除缓存再重新加载
  2. 加载时添加networkPolicy(NetworkPolicy.NO_CACHE)和memoryPolicy(MemoryPolicy.NO_CACHE)
  3. 使用stableKey()配合invalidate()

其中上传后尝试清除缓存的完整代码示例:

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
        Request.Method.POST,
        String.format("%s/v1/documents/cashierapp/%s", serverurl, Constant.getInstance().MERCHANT.getMobile()),
        postData,
        response -> {
            Trace.i("ProfileImgHttpPostTask", response.toString());
            Constant.getInstance().VolleyParams.remove("Authorization");
            Constant.getInstance().VolleyParams.put("Authorization", Constant.getInstance().MERCHANT.getToken());

            // 尝试清除旧头像缓存
            Picasso.get().invalidate(Constant.getInstance().MERCHANT.getProfPic());

            Picasso.get()
                    .load(Constant.getInstance().MERCHANT.getProfPic())
                    .resize(width, width)
                    .centerInside()
                    .placeholder(R.drawable.avatar)
                    .error(R.drawable.avatar)
                    .into(profPicView);


        },
        error -> {
            Constant.getInstance().VolleyParams.remove("Authorization");
            Constant.getInstance().VolleyParams.put("Authorization", Constant.getInstance().MERCHANT.getToken());
            Trace.i("ProfileImgHttpPostTask", "HTTP " + error.networkResponse.statusCode + "\n" + new String(error.networkResponse.data, StandardCharsets.UTF_8));
        }
) {
    @Override
    public Map<String, String> getHeaders() {
        Map<String, String> params = Constant.getInstance().VolleyParams;
        params.put("appid", CashierApp.getInstance().appid);
        params.put("Authorization", String.format("Bearer %s", CashierApp.getInstance().token));
        return params;
    }
};
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
                30000,
                1,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT))
        .setShouldCache(false)
        .setShouldRetryServerErrors(false)
        .setShouldRetryConnectionErrors(true);
Constant.getInstance().getQueue().add(jsonObjectRequest);

正确处理方式

方法1:给URL添加唯一标识参数(推荐)

Picasso的缓存完全基于URL,只要URL变化就会重新请求新资源。在头像上传成功后,给原URL拼接一个唯一参数(比如更新时间戳、后端返回的版本号):

// 上传成功后生成唯一标识(可以用当前时间戳,或者从接口返回的更新标识)
long updateMarker = System.currentTimeMillis();
String updatedAvatarUrl = Constant.getInstance().MERCHANT.getProfPic() + "?v=" + updateMarker;

// 更新MERCHANT中的头像URL,确保后续所有加载逻辑都用新URL
Constant.getInstance().MERCHANT.setProfPic(updatedAvatarUrl);

// 重新加载头像
Picasso.get()
    .load(updatedAvatarUrl)
    .resize(width, width)
    .centerInside()
    .placeholder(R.drawable.avatar)
    .error(R.drawable.avatar)
    .into(profPicView);

每次更新头像都更换参数值,就能彻底绕过缓存问题,同时不影响其他图片的缓存效率。

方法2:强制清除Picasso磁盘缓存(不推荐频繁使用)

如果无法修改URL,可以直接清除Picasso的整个磁盘缓存,但这会清空所有图片缓存,影响整体加载性能,仅适合特殊场景:

// 清除磁盘缓存必须在子线程执行
new Thread(() -> {
    try {
        Picasso.get().cache.clear();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 回到主线程重新加载头像
    runOnUiThread(() -> {
        Picasso.get()
            .load(Constant.getInstance().MERCHANT.getProfPic())
            .resize(width, width)
            .centerInside()
            .placeholder(R.drawable.avatar)
            .error(R.drawable.avatar)
            .into(profPicView);
    });
}).start();

方法3:调整服务器缓存策略

检查服务器返回图片时的Cache-Control响应头,如果设置了过长的max-age或者immutable,会导致客户端缓存无法及时失效。可以让后端修改图片接口的缓存配置,比如设置Cache-Control: no-cache或者较短的有效期,确保客户端能主动校验资源是否更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:47:39