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?

Foi útil?

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));
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top