Недействительный кеш в Пикассо

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

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


person Maarten    schedule 25.02.2014    source источник
comment
после Picasso.with(getActivity()).invalidate(file); как я могу снова кэшировать?   -  person tux-world    schedule 31.05.2017


Ответы (13)


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

Picasso.with(getActivity()).invalidate(file);
person mes    schedule 15.02.2015
comment
Что ж, это делает один файл недействительным. По-прежнему нет способа сделать недействительным весь кеш. Во всяком случае, я ответил на это почти год назад, поэтому я не удивлен, что они добавили это с тех пор. - person shalafi; 22.02.2015
comment
Да, он делает недействительным один файл, как и хотел автор, нет необходимости очищать весь кеш, это неэффективно. Вы сами год назад пробовали реализовать это в Пикассо? - person mes; 22.02.2015
comment
Убедитесь, что вы используете последнюю версию Picasso, иначе может появиться IllegalStateException. github.com/square/picasso/commit/ - person Jared Rummler; 07.03.2015
comment
invalidate не работает, изображение все еще остается в кеше диска - person user5155835; 28.10.2015
comment
Вам необходимо загрузить изображение с помощью Picasso.with(imageView.getContext()).load(imageUrl).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);, поскольку invalidate () не очищает сетевой кеш - person Joe Maher; 02.03.2016
comment
@shalafi Picasso.with(getActivity()).cache.clear(); очистит весь кеш. - person Sanket Berde; 27.01.2017
comment
@mes .invalidate(url) может быть кеширован после повторного получения изображения с URL-адреса? - person tux-world; 31.05.2017
comment
@shalafi кеш полей больше не является общедоступным - person RJFares; 15.08.2017
comment
@RJFares кеш полей всегда имел видимость пакета, поэтому необходимо поместить класс Tools в правильный пакет. - person shalafi; 15.08.2017
comment
@shalafi, на самом деле, я увидел ваш ответ, пользовательский класс. Можно ли с его помощью удалить конкретный файл вместо всего кеша? - person RJFares; 15.08.2017

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

package com.squareup.picasso;

public class PicassoTools {

    public static void clearCache (Picasso p) {
        p.cache.clear();
    }
}

Поскольку кеш имеет видимость пакетов, этот служебный класс может очистить кеш за вас. Вам просто нужно назвать это:

PicassoTools.clearCache(Picasso.with(context));
person shalafi    schedule 08.05.2014
comment
Как получить доступ к этому классу из файла jar? - person TheLettuceMaster; 17.05.2014
comment
Вам не нужно получать доступ к банке. вам нужно создать этот файл и поместить его в нужный пакет (com.squareup.picasso) - person shalafi; 19.05.2014
comment
О, я вижу. Имеет смысл. Спасибо. - person TheLettuceMaster; 19.05.2014
comment
Есть ли способ сделать это, если вы используете Gradle с Android Studio вместо файла jar надстройки? - person TheLettuceMaster; 12.07.2014
comment
нам нужно создать этот файл внутри picasso jar? - person virendrao; 17.11.2014
comment
Нет, вам не нужно прикасаться к банке Пикассо, вам просто нужно создать файл в правильном пакете. - person shalafi; 19.11.2014
comment
Жалко, что Picasso.with(getApplication()).cache.clear(); не работает. Было бы намного чище. - person Michael Schmidt; 04.04.2015
comment
Поле Picasso.cache не видно !! - person Iman Marashi; 25.03.2016
comment
Вот почему вы должны поместить этот класс в указанный пакет - person shalafi; 25.03.2016
comment
похоже, не работает, я попытался вызвать эту функцию, а затем открыл свой фрагмент с изображениями, и он мгновенно показал изображения в просмотрах изображений (из кеша) ... в первый раз, чтобы загрузить их, обычно требуется некоторое время, но все равно мгновенно и память, используемая приложением, не уменьшается после вызова этой функции, поэтому НЕ РАБОТАЕТ - person user924; 02.03.2018

Отмените проверку кеша памяти и кеша диска, указав политику памяти с помощью флага: 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);
person Виталий Ермолович    schedule 10.03.2015
comment
Спасибо! Добавление .networkPolicy (NetworkPolicy.NO_CACHE) сработало для меня. - person Can Uludağ; 15.10.2015
comment
По этому ответу изображения никогда не кешируются! так зачем это использовать? - person Iman Marashi; 25.03.2016
comment
@ImanMarashi полезно, если вы обычно работаете с одним и тем же URL-адресом и другим значением изображения (пример: amazonws.com/yourProject/user_profile_images/user1/profile.jpg. URL-адрес никогда не изменяется, но его значение изменяется. - person Borja; 11.04.2016

Попробуй использовать:

Picasso.with(ctx).load(new File("/path/to/image")).skipMemoryCache().into(imageView)
person dercilima    schedule 27.02.2014
comment
Это работает, однако я бы хотел, чтобы изображение сохраняло изображение в кеше, но не читало его, если мы знаем, что изображение устарело! Я обнаружил, что сделать это в Пикассо как есть невозможно, поэтому отмечу ваш ответ как правильный. - person Maarten; 04.03.2014
comment
Хотел как-то обновить ранее загруженное изображение. skipMemoryCache () сделал свое дело! Спасибо! - person russellhoff; 19.01.2015
comment
Сейчас это устарело - person Rob; 06.04.2017

Порядок поиска изображений в Picasso: Кэш памяти -> Кэш диска -> Сеть.

Итак, есть несколько сценариев, по которым нам нужно сделать недействительным кеш в 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, а выполняется только фоновая загрузка для использования позже.

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

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

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

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

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

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

person NguyenDat    schedule 12.10.2016

Что вы можете сделать, если хотите удалить весь кеш сразу, - это создать собственный Picasso.LruCache, а затем использовать для него метод clear.

Вот образец:

Picasso.Builder builder = new Picasso.Builder(this);
LruCache picassoCache = new LruCache(this);
builder.memoryCache(picassoCache);
Picasso.setSingletonInstance(builder.build());

Чтобы очистить кеш:

picassoCache.clear();
person Aerilys    schedule 20.03.2015
comment
Та же рекомендация из библиотеки Picasso: github.com/square/picasso/issues/935 - person vmeyer; 11.01.2019

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

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-cache».

person Lawrence Kesteloot    schedule 31.07.2014

Вы можете очистить кеш изображений 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();
person Stanley Ko    schedule 14.12.2015
comment
Единственное решение, которое сработало для меня. - person Bitcoin Cash - ADA enthusiast; 25.03.2021

Не зацикливается, но этот подход устранил мою проблему с кешем и 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);
person João Machete    schedule 23.04.2015

В принятом ответе здесь отсутствует очень важная часть. Я нашел уловку отсюда: 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);

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

person OrangeTree    schedule 28.09.2016

Вы можете пропустить кэш памяти 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"

person Android Dev    schedule 22.03.2017

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

person Ilan Klinghofer    schedule 14.02.2015

вместо этого используйте 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() вы его shutdown(), чтобы использовать повторно.

person Amol Desai    schedule 15.12.2015