Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android picasso clear cache

I am using Picasso to show one's portrait, when the protrait is changed, I want to clear this user's cache(or all users' portrait cache), here is my code, and it doesn't work,anyone can help me?

LruCache lruCache = new LruCache(context);
lruCache.clear();
Picasso picasso = new Picasso.Builder(context).memoryCache(lruCache).build();
picasso.load(portraitUrl).resize(50, 50).centerCrop().error(R.drawable.user_portrait).into(portaitView);
like image 987
Gaopeng Avatar asked Mar 07 '14 06:03

Gaopeng


People also ask

How do I refresh my Picasso library?

The reason is that Picasso stores that incorrect image in cache. The only way to reload image is to disable cache completely for that request (not recommended) or clear cache before reloading image. To do it you have to create a new file in com. squareup.

What is Picasso library in Android?

Picasso is open source and one of the widely used image download libraries in Android. It is created and maintained by Square. It is among the powerful image download and caching library for Android. Picasso simplifies the process of loading images from external URLs and displays them on your application.


2 Answers

In the recent versions of Picasso, there is a new method for invalidate, without any workarounds, so I think that custom PicassoTools class mentioned earlier, is now obsolete

Picasso.with(getActivity()).invalidate(file);
like image 184
mes Avatar answered Oct 15 '22 00:10

mes


I was facing the same problem and none of the solutions was acceptable for me... So I at least made a solution with reflection. I don't use crop, resize and so on, so my clear function only works if you only use load(url) with resizing, cropping, transformations... But I customized the complete getKey function, so this should at least be a big help to extend the clear function. Or just make the getKeyfunction public and change the clear(uri) function to clear(key)...

I just copied the key function from the source code and adopted it.

Just get the picasso instance from my tools class and everything should work (instead of having an context provider like me, you can for example add a init function, to initialise the PicassoTools class, with for example the application context).

Just use the following tools class:

public class PicassoTools
{
private static Picasso picasso = null;
private static CustomLruCache lruCache = null;

private static CustomLruCache getCache()
{
    if (lruCache == null)
        lruCache = new CustomLruCache(MainApp.getAppContext());
    return lruCache;
}

public static Picasso getPicasso()
{
    if (picasso == null)
        picasso = new Picasso.Builder(MainApp.getAppContext()).memoryCache(getCache()).build();
    return picasso;
}

public static void clear(Uri uri)
{
    getCache().remove(getKey(uri));
}

public static void clearCache()
{
    getCache().clear();
    // Picasso.with(MainApp.getAppContext()).cache.clear();
}

public static void clearCache(Context c)
{
    getCache().clear();
    // Picasso.with(c).cache.clear();
}

private static final int KEY_PADDING = 50; // Determined by exact science.

private static String getKey(Uri uri)
{
    return getKey(uri, null, 0, 0, false, false, null);
}

private static String getKey(Uri uri, Integer resourceId, int targetWidth, int targetHeight, boolean centerCrop, boolean centerInside, List<Transformation> transformations)
{
    StringBuilder builder = new StringBuilder();
    if (uri != null)
    {
        String path = uri.toString();
        builder.ensureCapacity(path.length() + KEY_PADDING);
        builder.append(path);
    }
    else
    {
        builder.ensureCapacity(KEY_PADDING);
        builder.append(resourceId);
    }
    builder.append('\n');

    if (targetWidth != 0)
    {
        builder.append("resize:").append(targetWidth).append('x').append(targetHeight);
        builder.append('\n');
    }
    if (centerCrop)
    {
        builder.append("centerCrop\n");
    }
    else if (centerInside)
    {
        builder.append("centerInside\n");
    }

    if (transformations != null)
    {
        // noinspection ForLoopReplaceableByForEach
        for (int i = 0, count = transformations.size(); i < count; i++)
        {
            builder.append(transformations.get(i).key());
            builder.append('\n');
        }
    }

    return builder.toString();
}
}

And the extended cache class:

public class CustomLruCache extends LruCache
{
public CustomLruCache(Context context)
{
    super(context);
}

public CustomLruCache(int value)
{
    super(value);
}

@Override
public Bitmap get(String key)
{
    L.d(this, key);
    return super.get(key);
}

public void remove(String key)
{
    try
    {
        Bitmap value = map.remove(key);

        Field fieldSize = LruCache.class.getDeclaredField("size");
        fieldSize.setAccessible(true);
        Integer size = (Integer) fieldSize.get(this);
        size -= Utils.getBitmapBytes(value);
        fieldSize.set(this, size);

        Field fieldEvictionCount = LruCache.class.getDeclaredField("evictionCount");
        fieldEvictionCount.setAccessible(true);
        Integer evictionCount = (Integer) fieldEvictionCount.get(this);
        evictionCount++;
        fieldEvictionCount.set(this, evictionCount);

    }
    catch (IllegalArgumentException e)
    {
        L.e(this, e);
    }
    catch (IllegalAccessException e)
    {
        L.e(this, e);
    }
    catch (NoSuchFieldException e)
    {
        L.e(this, e);
    }
}
}

PS: inspired by Invalidate cache in Picasso

like image 28
prom85 Avatar answered Oct 14 '22 22:10

prom85