Invalidar o cache do Picasso
-
21-12-2019 - |
Pergunta
Eu carregar uma imagem de disco usando o Picasso, por exemplo, Picasso.with(ctx).load(new File("/path/to/image")).into(imageView)
, mas sempre que eu salvar uma nova imagem em que o arquivo e atualizar o meu ImageView
, Picasso ainda tem o bitmap armazenado em cache.
É possível invalidar o cache de Picasso?
Solução
Em versões recentes do Picasso, existe um novo método para invalidar, sem quaisquer soluções alternativas, então eu acho que o costume PicassoTools classe mencionado anteriormente, é agora obsoleto, neste caso,
Picasso.with(getActivity()).invalidate(file);
Outras dicas
Na verdade, com base na sua própria resposta, há uma maneira mais fácil de fazê-lo sem grandes biblioteca.Adicionar esta classe com.squareup.picasso pacote.
package com.squareup.picasso;
public class PicassoTools {
public static void clearCache (Picasso p) {
p.cache.clear();
}
}
Porque cache tem pacote de visibilidade, este util classe pode limpar o cache para você.Você só tem que chamá-lo:
PicassoTools.clearCache(Picasso.with(context));
Anular a memória cache e cache de disco de seleção por indicar a memória política por bandeira:emoryPolicy.NO_CACHE e NetworkPolicy.NO_CACHE como abaixo trecho de código:
mPicasso.with(mContext)
.load(url)
.memoryPolicy(MemoryPolicy.NO_CACHE )
.networkPolicy(NetworkPolicy.NO_CACHE)
.resize(512, 512)
.error(R.drawable.login)
.noFade()
.into(imageView);
Tente usar:
Picasso.with(ctx).load(new File("/path/to/image")).skipMemoryCache().into(imageView)
Outra opção é excluir o diretório de cache em si, por exemplo, no aplicativo de inicialização:
deleteDirectoryTree(context.getCacheDir());
onde:
/**
* Deletes a directory tree recursively.
*/
public static void deleteDirectoryTree(File fileOrDirectory) {
if (fileOrDirectory.isDirectory()) {
for (File child : fileOrDirectory.listFiles()) {
deleteDirectoryTree(child);
}
}
fileOrDirectory.delete();
}
Que apaga todo o directório de cache, o que é bom se você quiser simular primeiro-uso de seu aplicativo.Se você apenas deseja excluir a Picasso cache, adicione "picasso-cache" para o caminho.
O que você pode fazer se você quiser apagar toda a cache de uma vez, é criar um personalizado Picasso.LruCache
, e , em seguida, usar o clear
método sobre ele.
Aqui está um exemplo:
Picasso.Builder builder = new Picasso.Builder(this);
LruCache picassoCache = new LruCache(this);
builder.memoryCache(picassoCache);
Picasso.setSingletonInstance(builder.build());
Para limpar o cache:
picassoCache.clear();
A ordem de pesquisa de imagem em Picasso é:Memória cache -> cache de Disco -> Rede
Então, há poucos cenário precisamos para invalidar o cache do Picasso:
1.De invalidação de cache de memória:
- Usercase:Quando a imagem já de atualização de cache de disco ou host remoto
Solução:Limpar o cache de Url, Arquivo, Uri se existe
mPicasso.with(appContext).invalidate(File); mPicasso.with(appContext).invalidate(Url); mPicasso.with(appContext).invalidate(Uri);
.
2.Invalidar o cache de memória e cache de disco Online
※nota: Online significa a atualização diretamente no ImageView
Exemplo do utilizador:Imagem atualizada no host remoto
Solução:Anular imagem na memória cache e cache de disco, em seguida, solicitar imagem no host remoto
mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE ) .networkPolicy(NetworkPolicy.NO_CACHE) .into(imageView);
-> Abortar cache de memória e cache de disco
.
3.Invalidar o cache de memória e cache de disco Offline
※ nota: Offline significa que a atualização não atualizar para ImageView, apenas busca em plano de fundo para usar mais tarde
- Exemplo do utilizador:Você sabe de imagem no host remoto atualizado, mas só deseja atualizar somente de cache para usar tarde (a não atualização em visualização de imagem)
Solução:buscar apenas
mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE) .networkPolicy(NetworkPolicy.NO_CACHE) .fetch();
※Nota:Usando fetch() é bom, mas é também consomem recursos de rede, então por favor, considere cuidadosamente, verifique cenário 4 abaixo, para uma melhor solução
4.Invalidar o cache de memória e cache de disco Offline se o cache de disco é existir
- Exemplo do utilizador:Apenas invalidar o cache, se já existe no cache de disco
Solução:Deve verificar o disco utilizando o parâmetro:NetworkPolicy.Cache off-line antes de buscar
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 é um incrível libs, espero squareup vai adicionar mais comodidade API para gerenciar cache no futuro próximo.
Você pode limpar cache de imagens de picasso, definindo o seu próprio cache e claro que.Este código foi testado em 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();
Não loop bonito, mas esta abordagem fixo o meu problema com o cache e Picasso.Somente use esta opção quando você deseja para invalidar o cache para um URL específico, este método é lento e provavelmente não é a maneira correta de fazer, mas funciona para mim.
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);
Uma parte muito importante está faltando o aceite resposta aqui.Eu encontrei o truque aqui: http://blogs.candoerz.com/question/124660/android-image-cache-is-not-clearing-in-picasso.aspx
Apenas chamando a seguinte linha, não limpar a cache de uma fotografia quando você usar opções personalizadas como redimensionar, cortar no centro etc quando visualizar a imagem original.
Picasso.with(getContext()).invalidate(file);
A solução:
Quando visualizar a imagem, use stableKey()
o método.
Picasso.with(getContext()).load(new File(fileUri))
.skipMemoryCache()
.placeholder(R.drawable.placeholder)
.stableKey(fileUri)
.into(imageview);
Em seguida, você pode limpar o cache do ficheiro posteriores chamando este:
Picasso.with(getContext()).invalidate(fileUri);
Espero que isso irá ajudá-lo.
Você pode ignorar o cache de memória, por skipMemoryCache()
consulte o seguinte
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"
Outra opção é salvar a nova imagem em um arquivo diferente do original.Desde o Picasso cache de mapa de bits é codificado fora do caminho do arquivo, o carregamento de uma nova imagem a partir de um outro arquivo resultará em um erro de cache.Este também tem o benefício de não ter que limpar todo o cache.
utilização shutdown()
em vez disso
Como por código-fonte;o encerramento vai deixar de aceitar novo pedido, bem como limpar todo o 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;
}
Além disso, você não pode encerramento instância singleton.Então, você precisa ter variável de instância para Picasso
.Não se esqueça de reinicializar picasso instância toda vez que você shutdown()
ele a fim de reutilizá-lo
File f = new File(path, name);
Picasso.with(this).invalidate(Uri.fromFile(f));