讓Picasso不快取圖片
問題描述:大多APP都有更換個人頭像的功能,樓主在開發中遇到了當更換頭像時,頭像沒有更換過來的問題,我用的是Picasso圖片請求框架,而這些載入圖片的框架一般都會有三級快取策略,當我們去載入一張圖片的時候就會優先查詢本地有沒有,當一張圖片已經載入過了之後就會快取到本地,雖然我們更換了頭像,但是圖片的url沒有變,所以再次載入的時候還是原來本地快取的圖片,而不是新的圖片,所以我們在載入圖片的時候可以設定不進行快取即可,這樣每次修改完頭像就載入的是新的頭像了…
寫法如下:
Picasso.with(context).load(url)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.error(R.drawable.default_icon)
.into(imageView);
其中.memoryPolicy(MemoryPolicy.NO_CACHE)這句的意思就是不進行快取。
.networkPolicy(NetworkPolicy.NO_CACHE)不進行網路圖片快取
標準行為
Picasso例項中有如下預設設定:
This instance is automatically initialized with defaults that are suitable to most implementations.
- LRU memory cache of 15% the available application RAM
- Disk cache of 2% storage space up to 50MB but no less than 5MB. (Note: this is only available on API > 14+ or if you are using a standalone library that provides a disk cache on all API levels like OkHttp)
- Three download threads for disk and network access.
快取的大小可以隨意更改,但顯然超出了這篇文章的範圍。回到主題上來:Picasso首先會嘗試去記憶體中載入影象,如果最近沒有載入過這張圖片,或者這張圖片並不存在於記憶體中,Picasso會去磁碟中檢查它的存在。如果磁碟中也不存在,則開啟網路請求。
此外,所有請求成功的圖片都會儲存到記憶體和磁碟中(除非為了釋放記憶體而被刪除)。總而言之就是,Picasso的載入路徑為記憶體->磁碟-> 網路。
可以通過自定義記憶體和網路載入策略改變Picasso的行為。接下來一起看下MemoryPolicy
。
記憶體策略
再說一遍,Picasso試圖先從記憶體中載入圖片。如果你想讓Picasso跳過記憶體查詢,可以在Picasso請求上呼叫memoryPolicy(MemoryPolicy policy, MemoryPolicy... additional)
。MemoryPolicy
是隻有兩個NO_CACHE
和NO_STORE
值的簡單列舉類。
舉例來說,可以使用NO_CACHE
限制Picasso從記憶體中載入圖片,示例如下:
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[1])
.memoryPolicy(MemoryPolicy.NO_CACHE)
.into(imageViewFromDisk);
如果你想知道如何使用NO_STORE
這個列舉:比如說,當前請求的圖片,只會被使用一次,那麼就應該呼叫.memoryPolicy(MemoryPolicy.NO_STORE)
。因此,Picasso不會把這張圖片放入到記憶體快取中。
當然,你可以在一個請求上聯合使用這些特性:
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[1])
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.into(imageViewFromDisk);
需要注意的是,呼叫.memoryPolicy(MemoryPolicy.NO_CACHE)
不會阻止Picasso從磁碟中查詢圖片!如果想跳過這兩個快取查詢,你需要看一下NetworkPolicy
。
網路策略
NetworkPolicy
調節磁碟快取的方式與MemoryPolicy
調節記憶體快取的方式一樣。甚至列舉的命名都是一樣的。
如果你想跳過磁碟快取,可以使用NetworkPolicy.NO_CACHE
作為引數,呼叫.networkPolicy(NetworkPolicy policy, NetworkPolicy... additional)
。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[2])
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(imageViewFromNetwork);
當前,你可以把之前提到的任何可能的配置進行合併:
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[2])
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(imageViewFromNetwork);
最後,NetworkPolicy
還有第三個可選引數:OFFLINE
。如果選擇這種模式,Picasso將會從記憶體或者磁碟中查詢圖片,如果這兩種快取中都沒有查詢到結果,即便網路連線可用,Picasso依然不會開啟網路請求去載入圖片。