Сбросить кеш в Пикассо


я загружаю изображение с диска с помощью Пикассо, например, Picasso.with(ctx).load(new File("/path/to/image")).into(imageView), но всякий раз, когда я сохраняю новое изображение в этом файле, и обновить мой ImageView, Пикассо все еще имеет растровое изображение в кэше.

можно ли аннулировать кэш в Picasso?

14 70

14 ответов:

в последних версиях Picasso есть новый метод для invalidate, без каких-либо обходных путей, поэтому я думаю, что пользовательский класс PicassoTools, упомянутый ранее, теперь устарел в этом случае

Picasso.with(getActivity()).invalidate(file);

На самом деле, основываясь на вашем собственном ответе, есть более простой способ сделать это без разветвления библиотеки. Добавьте этот класс в com.квадрат.пакет Пикассо.

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)

другой вариант-удалить сам каталог кэша, например, при запуске приложения:

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.Аннулировать кэш памяти:

  • Usercase: когда изображение уже обновляется в кэше диска или удаленном хосте
  • решение: очистить кэш Url, файла, 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.Аннулировать кэш памяти и диск кэшOffline

※ Примечание: Offline среднее обновление не обновляется до ImageView, просто фоновая выборка для использования позже

  • случай пользователя: вы знаете, что изображение на удаленном хосте обновлено, но хотите обновить кэш только для последующего использования (Не обновлять в виде изображения)
  • решение: fetch only

     mPicasso.with(appContext)
        .load(url)
        .memoryPolicy(MemoryPolicy.NO_CACHE)
        .networkPolicy(NetworkPolicy.NO_CACHE)
        .fetch();
    

※Примечание: использование fetch () хорошо, но он также потребляет сетевой ресурс, поэтому, пожалуйста внимательно рассмотрите, проверьте сценарий 4 ниже для лучшего решения

4.Аннулировать кэш памяти и дисковый кэшOffline если дисковый кэш существует

  • случай пользователя: только аннулировать кэш, если он уже существует в дисковом кэше
  • решение: следует проверить диск с помощью параметра: NetworkPolicy.Автономный кэш перед выборкой

     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
        }
    });
    

Пикассо является удивительным libs, я надеюсь, что squareup добавит более удобный 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();

Не петля довольно, но этот подход исправил мою проблему с кэшем и Пикассо. Используйте это только тогда, когда вы хотите аннулировать кэш для определенного 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);

надеюсь, что это поможет.

можно пропустить кэш-памяти skipMemoryCache()

см. ниже

        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"

другой вариант-Сохранить новое изображение в другой файл, чем оригинал. Поскольку кэш растровых изображений Picasso отключен от пути к файлу, загрузка нового изображения из другого файла приведет к пропуску кэша. Это также имеет дополнительное преимущество - не нужно очищать весь кэш.

использовать shutdown() вместо Согласно исходному коду; 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. Не забудьте повторно инициализировать экземпляр picasso каждый раз, когда вы shutdown() это для того, чтобы использовать

File f = new File(path, name);
Picasso.with(this).invalidate(Uri.fromFile(f));