15

I'm trying to clear the cache memory of Picasso via Android coding.

Can anyone please help me in this issue..?

I have tried using the following code, but this was not useful in my case:

Picasso.with(getActivity()).load(data.get(pos).getFeed_thumb_image()).skipMemoryCache().into(image);
Nikola Despotoski
  • 46,951
  • 13
  • 114
  • 146
Parthiban M
  • 1,096
  • 1
  • 9
  • 29

8 Answers8

35

Use this instead :

 Picasso.with(getContext()).load(data.get(pos).getFeed_thumb_image()).memoryPolicy(MemoryPolicy.NO_CACHE).into(image);
Mohamed
  • 756
  • 11
  • 23
  • 3
    Didn't work for me. Hence I added .networkpolicy(NetworkPolicy.NO_CACHE) also. Then only worked. – karan Aug 03 '16 at 12:14
  • 6
    what about if want to cache all images for some time, but then clear all cache when I don't need it anymore? – user924 Mar 01 '18 at 21:41
12

Remove cache of Picasso like this.

public class Clear {

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

This util class can clear the cache for you. You just have to call it:

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

EDIT:
The class Clear must be in the package :

package com.squareup.picasso;

Because cache is not accessible from outside that package. Like in this answer: https://stackoverflow.com/a/23544650/4585226

Community
  • 1
  • 1
Murtaza Khursheed Hussain
  • 14,714
  • 7
  • 52
  • 78
  • 1
    Thanks for your answer. It throws error to change the method as non-static or change the class as static. Also it says that the "cache" is not visible in the following line: p.cache.clear(); – Parthiban M Dec 16 '14 at 13:22
  • it should work. We are calling static method of a public class. – Murtaza Khursheed Hussain Dec 16 '14 at 13:25
  • 2
    I'm using only the Picasso jar and I'm not using any external picasso libraries. And it says that "p.cache" is invisible. – Parthiban M Dec 16 '14 at 14:03
  • You should set the same package of the Picasso class for you Clear class. – andrea.rinaldi Sep 28 '15 at 15:38
  • plus 1 for the concept on how to access methods that are not public inside a jar – A.Alqadomi Dec 28 '17 at 07:48
  • seems doesn't work, I tried to call this function and then opened my fragment with images and it showed images in imageviews instantly (from cache)... for the first time to load them it usually takes some time, but it's still instantly and memory using by app doesn't decrease after calling this function, so DOES NOT work, https://stackoverflow.com/a/29173703/7767664 but this works – user924 Mar 01 '18 at 22:22
10

if you are trying to load an image through Json(from db) try clearing the networkCache for a better result.

Picasso.with(context).load(uri).networkPolicy(NetworkPolicy.NO_CACHE)
        .memoryPolicy(MemoryPolicy.NO_CACHE)
        .placeholder(R.drawable.bv_logo_default).stableKey(id)
        .into(viewImage_imageView);
Parthiban M
  • 1,096
  • 1
  • 9
  • 29
6

Instead of clearing the complete cache if one wants to refresh the image with the given Uri. try this Picasso.with(context).invalidate(uri); it internally removes the key from the cache maintained by Picasso.

Excerpt from Picasso.java /** * Invalidate all memory cached images for the specified {@code uri}. * * @see #invalidate(String) * @see #invalidate(File) */ public void invalidate(Uri uri) { if (uri == null) { throw new IllegalArgumentException("uri == null"); } cache.clearKeyUri(uri.toString()); }

Devendra Vaja
  • 3,437
  • 1
  • 16
  • 13
  • This worked perfectly for me and is indeed much more efficient than clearing the entire cache. This should be the accepted answer. – Dean Gurvitz Dec 27 '18 at 15:48
4

When activity destroy, unfortunately bitmap was not recycled if we're using Picasso. I try to programmatically recycle bitmap, what's loaded in to image view. There is a way to reference to loaded bitmap by using Target.

 Target mBackgroundTarget = new Target() {
        Bitmap mBitmap;

        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            if (bitmap == null || bitmap.isRecycled())
                return;

            mBitmap = bitmap;
            mBgImage.setImageBitmap(bitmap);
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // Do some animation
                }
            });
        }

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {
            recycle();
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {

        }

        /**
         * Recycle bitmap to free memory
         */
        private void recycle() {
            if (mBitmap != null && !mBitmap.isRecycled()) {
                mBitmap.recycle();
                mBitmap = null;
                System.gc();
            }
        }
    };

And when Activity destroy, I call onBitmapFailed(null) to recycle loaded bitmap.

@Override
protected void onDestroy() {
    super.onDestroy();
    try {
        if (mBackgroundTarget != null) {
            mBackgroundTarget.onBitmapFailed(null);
            Picasso.with(context).cancelRequest(mBackgroundTarget);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

But remember, DON'T CACHE IMAGE IN MEMORY by this case, It will cause Use recycled bitmap exception.

Picasso.with(context)
            .load(imageUrl)
            .resize(width, height)
            .memoryPolicy(MemoryPolicy.NO_CACHE)
            .into(mBackgroundTarget);

Hope this help.

Khai Nguyen
  • 2,915
  • 1
  • 28
  • 24
0

If you keep reference of your custom Downloader implementation you can clear cache.

public class PicassoUtil {
    private static Picasso sInstance;
    private static OkHttp22Downloader sDownloader;
    public  static Picasso getPicasso(Context context){
        if(sInstance == null) {
            sDownloader = new OkHttp22Downloader(context)
            Picasso.Builder builder = new Picasso.Builder(context);
            builder.downloader(sDownloader);
            sInstance = builder.build(sDownloader);
        }
        return sInstance;
    }
   public static void clearCache(){
      if(sDownloader != null){
        sDownloader.clearCache();
      }
   }
}

It is important to have access to your http client and its Cache. In my implementation there is access to the cache, hence clearing cache with clearCache() method.

Nikola Despotoski
  • 46,951
  • 13
  • 114
  • 146
0

i had the same problem. It worked for me. I used Picasso in RecycleView inside a dialog. When i closed dialog, picasso doesnt clear cache. But while you are using the dialog it clears image cache. However there is some cache that is not cleared. Maybe the cache that was not cleared is the last you seen in dialog before dialog.dismiss().

use this memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)

Picasso.with(activity).load(file).resize(100,100).centerCrop().memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE).into(contactImage, new com.squareup.picasso.Callback() {
               @Override
                public void onSuccess() {

                }

                @Override
                public void onError() {

                }
            });
Cunity
  • 141
  • 1
  • 7
0
 Picasso.with(this.getContext()).load(gamePlayer.getPlayerProfileUrl()).skipMemoryCache().into(iv);

This also works

Rushi Ayyappa
  • 2,620
  • 2
  • 13
  • 26