피카소에서 캐시를 무효화합니다
-
21-12-2019 - |
문제
i picasso 를 사용하여 디스크에서 이미지를로드합니다. 예를 들어, Picasso.with(ctx).load(new File("/path/to/image")).into(imageView)
, 해당 파일에 새 이미지를 저장할 때마다그리고 ImageView
를 새로 고침하십시오. Picasso에는 여전히 비트 맵이 캐시됩니다.
피카스에서 캐시를 무효화 할 수 있습니까?
해결책
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));
. 메모리 캐시 및 디스크 캐시를 Abort Flag : 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)
. 다른 옵션은 앱 시작과 같이 캐시 디렉토리 자체를 삭제하는 것입니다.
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.Validate 메모리 캐시 :
- usercase : 이미지가 이미 디스크 캐시 또는 원격 호스트에서 업데이트 됨
-
해결책 : URL, 파일, URI의 캐시 지우기
mPicasso.with(appContext).invalidate(File); mPicasso.with(appContext).invalidate(Url); mPicasso.with(appContext).invalidate(Uri);
.
2.InValidate 메모리 캐시 및 디스크 캐시 온라인
※ 참고 : 온라인 이미지보기
직접 업데이트-
사용자 사례 : 원격 호스트에서 이미지 업데이트
-
솔루션 : 메모리 캐시 및 디스크 캐시에서 이미지를 중단 한 다음 원격 호스트에서 이미지를 요청합니다
.mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE ) .networkPolicy(NetworkPolicy.NO_CACHE) .into(imageView);
-> 메모리 캐시 및 디스크 캐시 중단
.
3.Validate 메모리 캐시 및 디스크 캐시 오프라인
※ 참고 : 오프라인 평균 ImageView로 업데이트되지 않고 나중에 사용하는 배경 가져 오기
- 사용자 사례 : 원격 호스트에서 이미지를 알고 있지만 이후에 사용하기 위해서만 캐시 만 업데이트하려는 경우
-
솔루션 : Fetch 만
mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE) .networkPolicy(NetworkPolicy.NO_CACHE) .fetch();
※ 참고 참고 : FETCH ()를 사용하는 것이 좋지만 네트워크 리소스를 사용하므로 아래에서 시나리오 4를 확인하십시오
4.InValidate 메모리 캐시 및 디스크 캐시 오프라인 디스크 캐시가있는 경우
- 사용자 케이스 : 디스크 캐시에 이미있는 경우 캐시 만 무효화
-
솔루션 : 파라미터를 사용하여 디스크를 확인해야합니다. fetch
전에 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이며, 앞으로 나오는 미래에 캐시를 관리하기 위해 더 많은 편리한 API를 추가하기를 바랍니다.
자신만의 캐시를 설정하여 Picasso의 이미지 캐시를 지울 수 있습니다. 이 코드는 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-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);
.
이것이 도움이되기를 바랍니다.
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));