我使用Picasso从磁盘加载图像,例如,Picasso.with(ctx).load(new File("/path/to/image")).into(imageView)
但是每当我在该文件中保存新图像并刷新时ImageView
,Picasso仍然会缓存位图。
是否有可能使毕加索的缓存无效?
Answers:
在最近的Picasso版本中,有一个新的作废方法,没有任何解决方法,因此,我认为前面提到的自定义PicassoTools类现在在这种情况下已过时
Picasso.with(getActivity()).invalidate(file);
IllegalStateException
可能会抛出。github.com/square/picasso/commit/...
Picasso.with(imageView.getContext()).load(imageUrl).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);
为无效()不清除缓存联网
实际上,根据您自己的答案,有一种更简便的方法,而无需分叉库。将此类添加到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));
Picasso.with(getApplication()).cache.clear();
是行不通的。这样会更清洁。
通过以下方式中止内存缓存和磁盘缓存检查:通过标志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)
如果要一次删除所有缓存,可以做的是创建一个custom 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中搜索图像的顺序为:内存缓存->磁盘缓存->网络
因此,在少数情况下,我们需要使Picasso中的缓存无效:
1,使内存缓存无效:
解决方案:清除Url,File,Uri的缓存(如果存在)
mPicasso.with(appContext).invalidate(File);
mPicasso.with(appContext).invalidate(Url);
mPicasso.with(appContext).invalidate(Uri);
。
2.使内存缓存和磁盘缓存 联机无效
※注:在线均值直接更新为ImageView
用户案例:远程主机上的映像已更新
解决方案:中止内存缓存和磁盘缓存上的映像,然后在远程主机上请求映像
mPicasso.with(appContext)
.load(url)
.memoryPolicy(MemoryPolicy.NO_CACHE )
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(imageView);
->中止内存缓存和磁盘缓存
。
3.使内存缓存和磁盘缓存 脱机无效
※注意:离线意味着不更新到ImageView,只是后台获取以供以后使用
解决方案:仅获取
mPicasso.with(appContext)
.load(url)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.fetch();
※注意:使用fetch()很好,但也会消耗网络资源,因此请仔细考虑,请检查下面的情况4以获取更好的解决方案
4. 如果存在磁盘缓存,则使内存缓存和磁盘缓存无效脱机
解决方案:在获取数据之前,应使用参数: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)是一个了不起的库,我希望Squareup会在即将到来的将来增加更多的便利API来管理缓存。
另一个选择是删除缓存目录本身,例如在应用程序启动时:
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 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();
循环不漂亮,但是这种方法解决了我的缓存和毕加索问题。仅当您要使特定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);
这里接受的答案缺少一个非常重要的部分。我从这里找到了窍门: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);
希望这会有所帮助。
另一种选择是将新图像保存到与原始图像不同的文件中。由于Picasso位图缓存是从文件路径中键入的,因此从其他文件加载新图像会导致缓存未命中。这还具有不必清除整个缓存的副作用。
使用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
。别忘了每次都重新初始化毕加索实例shutdown()
,以便重新使用它
Picasso.with(getActivity()).invalidate(file);
如何再次缓存?