Picasso清除缓存内存

16

我正在尝试通过Android编程来清除Picasso的缓存内存。

有人能帮我解决这个问题吗..?

我已经尝试使用以下代码,但在我的情况下没有用:

Picasso.with(getActivity()).load(data.get(pos).getFeed_thumb_image()).skipMemoryCache().into(image);

还没有测试过,但我猜 Picasso.with(context).shutdown() 可能会有帮助。 - activesince93
8个回答

37

请使用这个替代:

 Picasso.with(getContext()).load(data.get(pos).getFeed_thumb_image()).memoryPolicy(MemoryPolicy.NO_CACHE).into(image);

4
对我没用,因此我还添加了 .networkpolicy(NetworkPolicy.NO_CACHE)。然后才行。 - karan
6
如果我想将所有图像缓存一段时间,但在不再需要时清除所有缓存,该怎么办? - user924
添加'.networkPolicy(NetworkPolicy.NO_CACHE)'。 - Mahmut K.

12

像这样清除 Picasso 的缓存。

public class Clear {

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

这个工具类可以帮助您清除缓存。您只需调用它:

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

编辑
类“Clear”必须在包中:

package com.squareup.picasso;

因为缓存不可从包外部访问。就像在这个答案中所述:https://dev59.com/rWEh5IYBdhLWcg3wyGDy#23544650


1
感谢您的回答。将方法更改为非静态或将类更改为静态会引发错误。同时,它指出以下行中的“cache”不可见:p.cache.clear(); - Parthiban M
它应该可以工作。我们正在调用公共类的静态方法。 - Murtaza Khursheed Hussain
2
我只使用了Picasso jar,没有使用任何外部的Picasso库。它说“p.cache”是不可见的。 - Parthiban M
你应该为你的Clear类设置与Picasso类相同的包。 - andrea.rinaldi
在如何访问jar文件内部不公开方法的概念上加1 - A.Alqadomi
似乎不起作用,我尝试调用这个函数然后打开带有图像的碎片,它立即在ImageViews中显示图像(来自缓存)...第一次加载它们通常需要一些时间,但它仍然是立即的,并且调用此函数后应用程序使用的内存不会减少,所以它不起作用,https://dev59.com/rWEh5IYBdhLWcg3wyGDy#29173703 但这个可以。 - user924

11

如果您正试图通过 Json(从数据库)加载图像,请尝试清除网络缓存以获得更好的结果。

Picasso.with(context).load(uri).networkPolicy(NetworkPolicy.NO_CACHE)
        .memoryPolicy(MemoryPolicy.NO_CACHE)
        .placeholder(R.drawable.bv_logo_default).stableKey(id)
        .into(viewImage_imageView);

对于那些正在抽象化Picasso的人,我们该如何处理默认值? - Oliver Dixon
图片加载时间太长。 - Heena Arora

7

如果想要使用给定的Uri刷新图像,而不是清除整个缓存。可以尝试这个方法Picasso.with(context).invalidate(uri);,它会自动从Picasso维护的缓存中移除对应的键。

摘自Picasso.java /** * 为指定的{@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()); }


这对我来说完美地运作了,确实比清除整个缓存要高效得多。这应该是被采纳的答案。 - Dean Gurvitz

4

当activity被销毁时,如果我们使用Picasso,不幸的是bitmap没有被回收。我尝试通过编程的方式回收bitmap,即加载到image view中的bitmap。可以使用Target引用加载的bitmap。

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

当Activity被销毁时,我调用onBitmapFailed(null)来回收加载的位图。
@Override
protected void onDestroy() {
    super.onDestroy();
    try {
        if (mBackgroundTarget != null) {
            mBackgroundTarget.onBitmapFailed(null);
            Picasso.with(context).cancelRequest(mBackgroundTarget);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

但请记住,不要通过这种方式将图像缓存在内存中,它会导致“使用已回收的位图”异常。
Picasso.with(context)
            .load(imageUrl)
            .resize(width, height)
            .memoryPolicy(MemoryPolicy.NO_CACHE)
            .into(mBackgroundTarget);

希望这能帮到你。

0
如果你保留了你的自定义“Downloader”实现的引用,你可以清除缓存。
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();
      }
   }
}

拥有访问您的http客户端及其Cache非常重要。在我的实现中,可以访问缓存,因此可以使用clearCache()方法清除缓存。


0
我曾经遇到过同样的问题。 这对我有用。 我在对话框中使用了RecycleView中的Picasso。当我关闭对话框时,picasso不会清除缓存。但是在您使用对话框时,它会清除图像缓存。然而,仍有一些缓存未被清除。也许未清除的缓存是您在对话框中看到的最后一个缓存,然后才执行dialog.dismiss()。

使用此代码 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() {

                }
            });

0
 Picasso.with(this.getContext()).load(gamePlayer.getPlayerProfileUrl()).skipMemoryCache().into(iv);

这也可以工作


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接