Вопрос

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

Можно ли сделать недействительным кэш в Picasso?

Это было полезно?

Решение

В последних версиях Picasso появился новый метод invalidate без каких-либо обходных путей, поэтому я думаю, что пользовательский класс 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();
    }
}

Поскольку cache имеет видимость пакета, этот класс 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 таков:Кэш памяти -> Дисковый кэш -> Сетевой

Итак, есть несколько сценариев, которые нам нужны для аннулирования кэша в Picasso:

1.Аннулируйте кэш памяти:

  • Регистр пользователя:Когда изображение уже обновлено в дисковом кэше или на удаленном хосте
  • Решение:Очистить кэш 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.Аннулируйте кэш памяти и дисковый кэш Не в сети

※ примечание: Не в сети имею в виду обновление, а не обновление до ImageView, просто фоновую выборку для последующего использования

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

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

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

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

  • Пользовательский кейс:Аннулирует кэш только в том случае, если он уже существует в дисковом кэше
  • Решение:Следует проверить диск с помощью параметра:Сетевая политика.АВТОНОМНЫЙ кэш перед извлечением

     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 для управления кэшем.

Вы можете очистить кэш изображений 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();

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

градиент compile "com.squareup.picasso:picasso:2.4.0"

Другой вариант - сохранить новое изображение в файл, отличный от исходного.Поскольку растровый кэш 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;
  }

Также вы не можете отключить экземпляр singleton.Итак, вам нужно иметь переменную экземпляра для Picasso.Не забывайте повторно инициализировать экземпляр picasso каждый раз, когда вы shutdown() это для того, чтобы повторно использовать его

File f = new File(path, name);
Picasso.with(this).invalidate(Uri.fromFile(f));
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top