使Picasso中的缓存失效
-
21-12-2019 - |
题
我从磁盘加载图像使用 毕加索, ,例如, Picasso.with(ctx).load(new File("/path/to/image")).into(imageView)
, ,但每当我在该文件中保存一个新图像,并刷新我的 ImageView
, ,毕加索仍然有缓存的位图。
是否有可能使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();
}
}
.
因为缓存具有包可见性,因此此Util类可以为您清除缓存。你只需打电话给它:
PicassoTools.clearCache(Picasso.with(context));
. 中止内存缓存和磁盘缓存检查通过标志: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)
. 另一个选项是删除缓存目录本身,例如App Startup:
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缓存,请向路径添加“picasso-cache”。
如果你想一次删除所有缓存,你可以做的是创建一个自定义 Picasso.LruCache
, ,然后使用 clear
方法就可以了。
这是一个示例:
Picasso.Builder builder = new Picasso.Builder(this);
LruCache picassoCache = new LruCache(this);
builder.memoryCache(picassoCache);
Picasso.setSingletonInstance(builder.build());
清除缓存:
picassoCache.clear();
毕加索的搜索映像顺序是: 内存缓存 - >磁盘缓存 - >网络
所以,很少的场景我们需要在Picasso中无效缓存:1. alidate内存缓存:
- usercase:当图像已经在磁盘缓存或远程主机中更新时
-
解决方案:URL,文件,URI的清除缓存,如果存在
mPicasso.with(appContext).invalidate(File); mPicasso.with(appContext).invalidate(Url); mPicasso.with(appContext).invalidate(Uri);
。
2. alidate内存缓存和磁盘缓存 在线
※注意:在线平均更新直接以imageview
-
用户案例:在远程主机上更新的图像
-
解决方案:在存储器缓存和磁盘缓存上的中止图像,然后请求远程主机上的图像
.mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE ) .networkPolicy(NetworkPolicy.NO_CACHE) .into(imageView);
- >中止内存缓存和磁盘缓存
。
3.validate内存缓存和磁盘缓存 离线
※注意:离线平均更新不会更新到imageview,只是背景上获取稍后
- 用户案例:您知道更新的远程主机上的图像,但只需要更新缓存,仅更新以后使用(不更新到图像视图)
-
解决方案:仅获取
mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE) .networkPolicy(NetworkPolicy.NO_CACHE) .fetch();
※注意:使用fetch()很好,但它也消耗了网络资源,所以请仔细考虑下面的方案4以更好的解决方案
4.validate内存缓存和磁盘缓存 脱机如果磁盘缓存存在
- 用户案例:如果已存在磁盘缓存 中已存在,则只有无效缓存
-
解决方案:应使用参数检查磁盘:NetworkPolicy.Offline缓存在获取之前
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是一个惊人的libs,我希望方形up将增加更多的便利API来管理即将到来的未来中的缓存。
您可以通过设置自己的缓存清除皮卡的图像缓存并清除。 此代码在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();
. 不循环漂亮,但这种方法修复了我的问题和picasso。只有当您想要为特定网址无效缓存时才使用此方法,这种方法很慢,可能不是正确的方式,但为我工作。
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);
. 这里接受的答案中缺少一个非常重要的部分。我从这里找到了诀窍: 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);
然后,您可以稍后通过调用this来清除此文件的缓存:
Picasso.with(getContext()).invalidate(fileUri);
希望这会有所帮助。
You can skip memory cache by skipMemoryCache()
see the following
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"
Another option is to save the new image into a different file than the original. Since the Picasso bitmap cache is keyed off of the file path, loading the new image from a different file will result in a cache miss. This also has the side benefit of not having to clear the entire cache.
use shutdown()
instead
As per source code; shutdown will stop accepting further request as well as clear all cache
/** 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;
}
Also you can not shutdown singleton instance.
So you need to have instance variable for Picasso
. Do not forget to reinitialize picasso instance everytime you shutdown()
it in order to reuse it
File f = new File(path, name);
Picasso.with(this).invalidate(Uri.fromFile(f));