2014-02-25 583 views
65

我使用Picasso(例如Picasso.with(ctx).load(new File("/path/to/image")).into(imageView))從磁盤加載圖像,但每當我在該文件中保存新圖像並刷新我的ImageView時,畢加索仍保留位圖緩存。使畢加索的緩存無效

是否有可能使Picasso中的緩存無效?

+0

後'Picasso.with(getActivity())無效(文件);'我怎麼能再次緩存? –

回答

77

在最新版本的畢加索,對於無效的新方法,而無需任何變通,所以我覺得剛纔提到的自定義PicassoTools類,現在是在這種情況下,過時的

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

那麼,這確實無效的單個文件。仍然沒有辦法使所有緩存失效。 無論如何,我在一年前回復說,所以我並不感到驚訝,他們自那時起就加入了它。 – shalafi

+0

是的,它作爲一個單獨的文件無效,正如作者所希望的那樣,不需要清除整個緩存,這是無效的。你是否在一年前嘗試在畢加索自己實現它? – mes

+0

確保您使用的是Picasso的最新版本,否則可能會拋出'IllegalStateException'。 https://github.com/square/picasso/commit/4fd76a03e389d9f792393a0889398252a5b3b112 –

14

嘗試使用:

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

這是有效的,但我希望圖像*存儲*圖像緩存,只是沒有讀取它,如果我們知道圖像陳舊!我發現在畢加索現在不可能這樣做,所以我會將你的答案標記爲正確的。 – Maarten

+0

我想以某種方式刷新以前加載的圖像。 skipMemoryCache()做到了!謝謝! – russellhoff

+0

這不適用於我..它仍然保存在緩存中。 – mango

74

事實上,根據你自己的答案,有做它沒有建立該庫更簡單的方法。將此類添加到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)); 
+0

如何從jar文件訪問此類? – KickingLettuce

+17

您不必訪問jar。你必須創建這個文件並將它放在正確的包中(com.squareup.picasso) – shalafi

+0

哦,我明白了。非常有意義。謝謝。 – KickingLettuce

10

另一種方法是刪除緩存目錄本身,例如在應用程序啓動時:

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-cache」添加到路徑中。

+1

謝謝!只有這對我有效! – DBragion

+0

@勞倫斯Kesteloot你能幫我解決這個問題嗎? http://stackoverflow.com/questions/33657619/android-error-onbackpressed-with-deletedirectorytree-method。我已經使用你的方法取得了巨大的成功,但我現在遇到了問題。在此先感謝 –

+1

其他答案只是擺脫內存緩存但不是光盤緩存 - 這也照顧了光盤! :) –

0

另一種方法是將新圖像保存到與原始文件不同的文件中。由於畢加索位圖緩存是從文件路徑中刪除的,因此從其他文件加載新映像將導致緩存未命中。這也有不必清除整個緩存的副作用。

57

中止內存緩存和通過磁盤緩存檢查指示由標誌存儲器政策: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); 
+0

這工作對我來說 –

+0

謝謝!添加.networkPolicy(NetworkPolicy.NO_CACHE)爲我工作。 –

+0

通過回答此圖片永不緩存!那爲什麼要用它? –

9

如果你想一次刪除所有緩存,你能做的,就是創建一個自定義Picasso.LruCache,然後我們e上的clear方法。

這裏有一個例子:

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

要清除高速緩存:

picassoCache.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); 
7

您可以通過設置自己的緩存並清除,清除畢加索的圖像緩存。 此代碼已在畢加索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(); 
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的實例變量。不要忘了初始化畢加索例如每次你shutdown()它以重用

0
File f = new File(path, name); 
Picasso.with(this).invalidate(Uri.fromFile(f)); 
0

一個非常重要的部分是從接受的答案在這裏失蹤。我從這裏找到了訣竅: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); 

希望這會有所幫助。

8

畢加索搜索圖片的順序是: 內存緩存 - >磁盤高速緩存 - >網絡

所以有我們需要在畢加索無效緩存幾個場景:

1.Invalidate內存緩存:

  • Usercase:當圖像在磁盤高速緩存或遠程主機已經更新
  • 解決方案:如果存在

    mPicasso.with(appContext).invalidate(File); 
    mPicasso.with(appContext).invalidate(Url); 
    mPicasso.with(appContext).invalidate(Uri); 
    

URL,文件,烏里清除緩存。

2。無效的內存高速緩存和磁盤高速緩存在線

※注:在線意味着直接更新到ImageView的

  • 用戶案例:圖片更新遠程主機上

  • 解決方案:中止圖像內存緩存和磁盤緩存然後請求遠程主機上的映像

    mPicasso.with(appContext) 
        .load(url) 
        .memoryPolicy(MemoryPolicy.NO_CACHE) 
        .networkPolicy(NetworkPolicy.NO_CACHE) 
        .into(imageView); 
    

    - >中止存儲器高速緩存和磁盤高速緩存

3.Invalidate內存緩存和磁盤高速緩存離線

※注:離線平均更新不更新到ImageView的,只是背景提取使用後

  • 用戶案例:您知道遠程主機上的映像已更新,但只希望將緩存更新爲僅以後使用(未更新到映像視圖中)
  • Soluti上:只獲取

    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來管理緩存在未來的將來。

0

您可以通過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"