让毕加索caching失效

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

是否有可能使毕加索caching无效?

在最近的Picasso版本中,有一种新的无效方法,没有任何解决方法,所以我认为前面提到的定制PicassoTools类在这种情况下已经过时了

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

其实,根据你自己的答案,有一个更简单的方法来做到这一点,而不是分叉图书馆。 将此类添加到com.squareup.picasso包中。

 package com.squareup.picasso; public class PicassoTools { public static void clearCache (Picasso p) { p.cache.clear(); } } 

由于caching具有包可见性,因此此util类可以为您清除caching。 你只需要调用它:

 PicassoTools.clearCache(Picasso.with(context)); 

取消内存caching和磁盘caching检查通过标志指示内存策略: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); 

尝试使用:

 Picasso.with(ctx).load(new File("/path/to/image")).skipMemoryCache().into(imageView) 

另一个select是删除caching目录本身,例如在应用程序启动时:

 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(); } 

这将删除整个caching目录,如果你想模拟你的应用程序的第一次使用,这是很好的。 如果您只想删除毕加索caching,请将“picasso-cache”添加到path中。

如果要一次删除所有caching,可以执行的操作是创build一个自定义Picasso.LruCache ,然后使用clear方法。

这是一个示例:

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

清除caching:

 picassoCache.clear(); 

您可以通过设置自己的caching清除毕加索的图像caching并清除该caching。 此代码在毕加索2.5.0上进行了testing

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

毕加索search图像的顺序是:内存caching – >磁盘caching – >networking

所以我们需要使毕加索的caching失效的情况很less:

1.使内存caching无效:

  • 用户案例:当映像已经在磁盘caching或远程主机中更新时
  • 解决scheme:清除Url,File,Uri的caching(如果存在)

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

2.使内存caching和磁盘caching无效

※注意: 在线意味着更新直接ImageView

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

  • 解决scheme:中止内存caching和磁盘caching中的映像,然后在远程主机上请求映像

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

    – >中止内存caching和磁盘caching

3.使内存caching和磁盘caching失效无效

※注意: 离线平均更新不更新到ImageView,只是后台使用后取

  • 用户案例:您知道远程主机上的映像已更新,但仅仅需要将caching更新为仅在以后使用(不会更新到映像视图中)
  • 解决scheme:仅获取

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

※注意:使用fetch()虽然不错,但是也会消耗networking资源,所以请仔细考虑下面的scheme4,以获得更好的解决scheme

4.如果磁盘caching存在,则使内存caching和磁盘caching失效

  • 用户案例:只有在磁盘caching中已存在的情况下才会使caching失效
  • 解决scheme:应在检索之前使用参数NetworkPolicy.OFFLINEcaching检查磁盘

      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 } }); 

毕加索是一个了不起的库,我希望在即将到来的未来,squareup会增加更多的便利API来pipe理caching。

不循环漂亮,但这种方法解决了caching和毕加索的问题。 只有当你想使一个特定的URL的caching无效时才使用这个方法,这种方法很慢,可能不是正确的做法,但适用于我。

  String url = "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); 

另一种方法是将新图像保存到与原始文件不同的文件中。 由于毕加索位图caching被locking在文件path之外,因此从其他文件加载新映像将导致caching未命中。 这也有不必清除整个caching的副作用。

使用shutdown()而不是根据源代码; 关机将停止接受进一步的请求以及清除所有的caching

  /** 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; } 

你也不能closures单例实例。 所以你需要有Picasso实例variables。 不要忘记每次shutdown()时重新初始化毕加索实例,以便重用

 File f = new File(path, name); Picasso.with(this).invalidate(Uri.fromFile(f)); 

这里接受的答案中缺less一个非常重要的部分。 我发现这个技巧: http : //blogs.candoerz.com/question/124660/android-image-cache-is-not-clearing-in-picasso.aspx

只需调用以下行,当您使用自定义选项(如resize,居中裁剪等)显示原始图像时,不会清除照片的caching。 。Picasso.with(的getContext())无效(文件);

解决scheme:

显示图像时,使用stableKey()选项。

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

然后,可以通过调用以下命令清除此文件的caching: Picasso.with(getContext())。invalidate(fileUri);

希望这会有所帮助。

您可以通过skipMemoryCache()跳过内存caching

请参阅以下内容

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

gradle compile "com.squareup.picasso:picasso:2.4.0"