Сбросить кеш в Пикассо
я загружаю изображение с диска с помощью Пикассо, например, Picasso.with(ctx).load(new File("/path/to/image")).into(imageView)
, но всякий раз, когда я сохраняю новое изображение в этом файле, и обновить мой ImageView
, Пикассо все еще имеет растровое изображение в кэше.
можно ли аннулировать кэш в Picasso?
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()
это для того, чтобы использовать