问题描述:大多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依然不会开启网络请求去加载图片。