Недійсність кеш-пам’яті в Пікассо


76

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

Чи можна анулювати кеш-пам’ять у Пікассо?


1
після Picasso.with(getActivity()).invalidate(file);як я можу кешувати знову?
tux-world

Відповіді:


86

В останніх версіях Picasso існує новий метод недійсності, без будь-яких обхідних шляхів, тому я думаю, що власний клас PicassoTools, про який згадувалося раніше, у цьому випадку вже застарів.

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

3
Ну, це робить недійсністю один файл. Досі не існує методу анулювання всього кешу. У будь-якому випадку, я відповів на це майже рік тому, тому я не здивований, що вони додали це з тих пір.
шалафі

Так, він робить недійсним один файл, як того хотів автор, немає необхідності очищати весь кеш, це не ефективно. Ви спробували впровадити це у Пікассо самі рік тому?
мес

Переконайтеся, що ви користуєтесь останньою версією Пікассо, або її IllegalStateExceptionможуть кинути. github.com/square/picasso/commit/…
Джаред Раммлер

8
invalidate не працює, зображення все ще залишається в кеш-пам'яті диска
user5155835

8
Вам потрібно завантажити зображення, Picasso.with(imageView.getContext()).load(imageUrl).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);оскільки invalidate () не очищає кеш мережі
Джо Махер,

82

Насправді, виходячи з власної відповіді, існує простіший спосіб зробити це без розгалуження бібліотеки. Додайте цей клас до пакета com.squareup.picasso.

package com.squareup.picasso;

public class PicassoTools {

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

Оскільки кеш має видимість пакета, цей клас util може очистити кеш для вас. Вам просто потрібно назвати це:

PicassoTools.clearCache(Picasso.with(context));

21
Вам не потрібно отримувати доступ до банки. вам потрібно створити цей файл і помістити його в потрібний пакет (com.squareup.picasso)
шалафі

4
Чи є спосіб зробити це, якщо ви використовуєте Gradle з Android Studio замість додаткового файлу jar?
TheLettuceMaster

3
Ні, вам не потрібно чіпати банку Пікассо, вам просто потрібно створити файл у потрібній упаковці.
шалафі

7
Шкода, що Picasso.with(getApplication()).cache.clear();не виходить. Це було б набагато чистіше.
Michael Schmidt,

3
Поле Picasso.cache не видно !!
Іман Мараші

66

Скасувати перевірку кеш-пам’яті та кеш-пам’яті, указавши політику пам’яті прапором: 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);

1
Дякую! Додавання .networkPolicy (NetworkPolicy.NO_CACHE) у мене спрацювало.
Can Uludağ

1
За цією відповіддю зображення ніколи не кешуються! так навіщо це використовувати?
Іман Мараші

9
@ImanMarashi корисно, якщо ви зазвичай працюєте з однаковою URL-адресою та різним значенням зображення (Приклад: amazonws.com/yourProject/user_profile_images/user1/profile.jpg. URL-адреса ніколи не змінюється, але її значення змінюється.
Borja,

14

Спробуйте використати:

Picasso.with(ctx).load(new File("/path/to/image")).skipMemoryCache().into(imageView)

Це працює, однак я хотів би, щоб зображення зберігало зображення в кеш-пам'яті, просто не читало з нього, якщо ми знаємо, що зображення застаріле! Я з’ясував, що це неможливо зробити в Пікассо, як є, тому я позначу вашу відповідь як правильну.
Маартен

Я хотів якось оновити зображення, яке раніше було завантажено. skipMemoryCache () зробив свою справу! Дякую!
russellhoff

Зараз це застаріло
Роб

12

Що ви можете зробити, якщо ви хочете видалити весь кеш одночасно, це створити власний Picasso.LruCache, а потім використовувати clearна ньому метод.

Ось зразок:

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

Щоб очистити кеш:

picassoCache.clear();

Та сама рекомендація від lib Пікассо: github.com/square/picasso/issues/935
vmeyer,

12

Порядок пошуку зображення у Пікассо: кеш пам'яті -> кеш диска -> мережа

Отже, є кілька сценаріїв, якими нам потрібно скасувати кеш-пам’ять у Пікассо:

1.Застосувати кеш пам'яті:

  • Usercase: Коли зображення вже оновлюється в кеш-пам'яті диска або віддаленому хості
  • Рішення: Очистіть кеш Url, File, 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. Вимкніть кеш пам’яті та дисковий кеш в автономному режимі, якщо дисковий кеш існує

  • Випадок користувача: Недійсним кеш-пам’ять можна зробити лише у тому випадку, якщо він уже існує в кеш-пам’яті диска
  • Рішення: Перед переглядом слід перевірити диск за допомогою параметра: NetworkPolicy.OFFLINE

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

Пікассо - це дивовижні бібліотеки, я сподіваюся, що squareup додасть більше зручності API для управління кешем у майбутньому.


11

Іншим варіантом є видалення самого каталогу кешу, наприклад під час запуску програми:

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

Це видаляє весь каталог кешу, що добре, якщо ви хочете змоделювати перше використання програми. Якщо ви хочете лише видалити кеш-пам'ять Пікассо, додайте до шляху "кеш-пікассо".


@Lawrence Kesteloot чи не могли б ви допомогти мені з цим питанням? stackoverflow.com/questions/33657619/… . Я вже з великим успіхом використав ваш метод, але зараз у мене проблеми. Попереднє
спасибі

1
Інші відповіді просто позбавляються кеш-пам'яті, але не кеш-пам’яті диска - це теж піклується про диск! :)
Мохіт Сінгх

8

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

6

Не зациклюється, але такий підхід вирішив мою проблему з кешем та Пікассо. Використовуйте це лише тоді, коли ви хочете анулювати кеш для певної 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);

2

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

Сподіваюся, це допоможе.


1

Ви можете пропустити кеш пам'яті за допомогою 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"


0

Інший варіант - зберегти нове зображення у файлі, відмінному від оригіналу. Оскільки растровий кеш Picasso відключається від шляху до файлу, завантаження нового зображення з іншого файлу призведе до пропуску кешу. Це також має побічну перевагу в тому, що не потрібно очищати весь кеш.


0

використовувати 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()його використовуєте, щоб використовувати його повторно


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.