77

我使用Picasso从磁盘加载图像,例如 ,Picasso.with(ctx).load(new File("/path/to/image")).into(imageView)但每当我在该文件中保存新图像并刷新我的ImageView时,Picasso 仍然会缓存位图。

是否可以使毕加索中的缓存无效?

4

14 回答 14

86

实际上,根据您自己的答案,有一种更简单的方法可以在不分叉库的情况下做到这一点。将此类添加到 com.squareup.picasso 包中。

package com.squareup.picasso;

public class PicassoTools {

    public static void clearCache (Picasso p) {
        p.cache.clear();
    }
}

因为缓存具有包可见性,所以这个 util 类可以为您清除缓存。你只需要调用它:

PicassoTools.clearCache(Picasso.with(context));
于 2014-05-08T14:25:09.710 回答
86

在最近的毕加索版本中,有一种新的无效方法,没有任何变通方法,所以我认为前面提到的自定义 PicassoTools 类在这种情况下现在已经过时了

Picasso.with(getActivity()).invalidate(file);
于 2015-02-15T09:09:08.947 回答
66

通过标志指示内存策略中止内存缓存和磁盘缓存检查:emoryPolicy.NO_CACHE 和 NetworkPolicy.NO_CACHE,如下代码片段:

   mPicasso.with(mContext)
            .load(url)
            .memoryPolicy(MemoryPolicy.NO_CACHE )
            .networkPolicy(NetworkPolicy.NO_CACHE)
            .resize(512, 512)
            .error(R.drawable.login)
            .noFade()
            .into(imageView);
于 2015-03-10T12:52:07.647 回答
15

尝试使用:

Picasso.with(ctx).load(new File("/path/to/image")).skipMemoryCache().into(imageView)
于 2014-02-27T18:03:10.247 回答
13

Picasso中搜索图片的顺序是:内存缓存->磁盘缓存->网络

所以我们需要在 Picasso 中使缓存失效的场景很少:

1.使内存缓存失效:

  • 用例:当磁盘缓存或远程主机中的图像已经更新时
  • 解决方案:清除Url、File、Uri的缓存(如果存在)

    mPicasso.with(appContext).invalidate(File);
    mPicasso.with(appContext).invalidate(Url);
    mPicasso.with(appContext).invalidate(Uri);
    

.

2.Invalidate内存缓存和磁盘缓存 在线

※注:在线表示直接更新到ImageView

  • 用户案例:在远程主机上更新图像

  • 解决方案:中止内存缓存和磁盘缓存上的图像,然后请求远程主机上的图像

    mPicasso.with(appContext)
        .load(url)
        .memoryPolicy(MemoryPolicy.NO_CACHE )
        .networkPolicy(NetworkPolicy.NO_CACHE)
        .into(imageView);
    

    -> 中止内存缓存和磁盘缓存

.

3.Invalidate内存缓存和磁盘缓存 离线

※注意:离线意味着更新不更新到ImageView,只是后台获取稍后使用

  • 用户案例:您知道远程主机上的图像已更新,但只想更新缓存以供以后使用(不更新到图像视图)
  • 解决方案:仅获取

     mPicasso.with(appContext)
        .load(url)
        .memoryPolicy(MemoryPolicy.NO_CACHE)
        .networkPolicy(NetworkPolicy.NO_CACHE)
        .fetch();
    

※注意:使用 fetch() 很好,但也会消耗网络资源,所以请慎重考虑,请查看下面的场景 4 以获得更好的解决方案

4.Invalidate memory cache and disk cache Offline if disk cache is exist

  • 用户案例:仅当磁盘缓存中已存在时才使缓存无效
  • 解决方案:应该使用参数检查磁盘:NetworkPolicy.OFFLINE cache before fetch

     mPicasso.with(appContext)
        .load(url)
        .memoryPolicy(MemoryPolicy.NO_CACHE)
        .networkPolicy(NetworkPolicy.OFFLINE)
        .fetch(new Callback() {
            @Override
            public void onSuccess() {
                //Success: mean disk cache exist -> should do actual fetch
                picasso.load(url).fetch();
            }
    
            @Override
            public void onError() {
            //Failed: mean disk cache not exist
        }
    });
    

Picasso 是一个了不起的库,我希望 Squareup 将在未来添加更多方便的 API 来管理缓存。

于 2016-10-12T08:51:30.277 回答
12

另一种选择是删除缓存目录本身,例如在应用启动时:

deleteDirectoryTree(context.getCacheDir());

在哪里:

/**
 * Deletes a directory tree recursively.
 */
public static void deleteDirectoryTree(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory()) {
        for (File child : fileOrDirectory.listFiles()) {
            deleteDirectoryTree(child);
        }
    }

    fileOrDirectory.delete();
}

这会删除整个缓存目录,如果您想模拟应用程序的首次使用,这很好。如果您只想删除毕加索缓存,请将“picasso-cache”添加到路径中。

于 2014-07-31T18:50:48.400 回答
12

如果您想一次删除所有缓存,您可以做的是创建一个自定义Picasso.LruCache,然后使用该clear方法。

这是一个示例:

Picasso.Builder builder = new Picasso.Builder(this);
LruCache picassoCache = new LruCache(this);
builder.memoryCache(picassoCache);
Picasso.setSingletonInstance(builder.build());

要清除缓存:

picassoCache.clear();
于 2015-03-20T18:42:54.387 回答
8

您可以通过设置自己的缓存并清除它来清除毕加索的图像缓存。此代码已在 Picasso 2.5.0 上测试

private Picasso picasso;
private LruCache picassoLruCache;

picassoLruCache = new LruCache(context);

// Set cache
picasso = new Picasso.Builder(context) //
        .memoryCache(picassoLruCache) //
        .build();

// Clear cache
picassoLruCache.clear();
于 2015-12-14T08:36:06.713 回答
6

循环不好,但这种方法解决了我的缓存和毕加索问题。仅当您想使特定 URL 的缓存无效时才使用此方法,这种方法很慢,可能不是正确的方法,但对我有用。

    String url = "http://www.blablabla.com/Raiders.jpg";
    Picasso.with(this).invalidate(url);
    Picasso.with(this)
            .load(url)
            .networkPolicy(
                    NetworkUtils.isConnected(this) ?
                            NetworkPolicy.NO_CACHE : NetworkPolicy.OFFLINE)
            .resize(200, 200)
            .centerCrop()
            .placeholder(R.mipmap.ic_avatar)
            .error(R.mipmap.ic_avatar)
            .into(imageView);
于 2015-04-23T02:46:58.077 回答
2

这里接受的答案缺少一个非常重要的部分。我从这里找到了诀窍:http: //blogs.candoerz.com/question/124660/android-image-cache-is-not-clearing-in-picasso.aspx

只需调用以下行,当您在显示原始图像时使用调整大小、中心裁剪等自定义选项时,不会清除照片的缓存。

Picasso.with(getContext()).invalidate(file);

解决方案:

显示图像时,使用stableKey()方法。

Picasso.with(getContext()).load(new File(fileUri))
                         .skipMemoryCache()
                         .placeholder(R.drawable.placeholder)
                         .stableKey(fileUri)
                         .into(imageview);

然后,您可以稍后通过调用以下命令清除此文件的缓存:

Picasso.with(getContext()).invalidate(fileUri);

希望这会有所帮助。

于 2016-09-28T19:34:33.000 回答
1

您可以通过以下方式跳过内存缓存skipMemoryCache()

见下文

        Picasso.with(this)
            .load(IMAGE_URL)
            .skipMemoryCache()
            .placeholder(R.drawable.placeholder)
            .error(R.drawable.no_image)
            .into(mImageViewPicasso);

毕业典礼compile "com.squareup.picasso:picasso:2.4.0"

于 2017-03-22T05:48:20.353 回答
0

另一种选择是将新图像保存到与原始文件不同的文件中。由于 Picasso 位图缓存与文件路径无关,因此从不同的文件加载新图像将导致缓存未命中。这还有一个好处,就是不必清除整个缓存。

于 2015-02-14T17:50:41.393 回答
0

改用shutdown()根据源代码;shutdown 将停止接受进一步的请求并清除所有缓存

 /** Stops this instance from accepting further requests. */
  public void shutdown() {
    if (this == singleton) {
      throw new UnsupportedOperationException("Default singleton instance cannot be shutdown.");
    }
    if (shutdown) {
      return;
    }
    cache.clear();
    cleanupThread.shutdown();
    stats.shutdown();
    dispatcher.shutdown();
    for (DeferredRequestCreator deferredRequestCreator : targetToDeferredRequestCreator.values()) {
      deferredRequestCreator.cancel();
    }
    targetToDeferredRequestCreator.clear();
    shutdown = true;
  }

您也不能关闭单例实例。所以你需要有实例变量Picasso。不要忘记每次重新初始化 picasso 实例shutdown()以便重用它

于 2015-12-15T13:59:55.837 回答
0
File f = new File(path, name);
Picasso.with(this).invalidate(Uri.fromFile(f));
于 2016-07-06T09:22:47.393 回答