1. 前言
最近项目开发中使用到来Picasso,并且碰到了一个部分图片无法加载的问题,使用Glide可以正常加载,使用最新的Picasso3.0.0-SNAPSHOT版本也没有问题,最后使用Picasso自带的异常监听获取堆栈,并且在Github中找到的同样的问题,具体查阅:
https://github.com/square/picasso/issues/1514
所以,想详细的看看Picasso的详细用法和master分支上的源代码。
2. 基本介绍
Picasso 是Square 公司开源的Android 端的图片加载和缓存框架。图片的加载是一个令人很头疼的问题,因为涉及的内容比较多,比如网络请求,本地存储,图片缓存,图片回收等等,处理不好可能会出现图片变形内存泄漏等令开发者焦头烂额的问题,但是Picasso帮我们做了很多事情,比如:
- 处理Adapter 中ImageView的回收和取消下载。
- 使用最小的内存 来做复杂的图片变换。比如高斯模糊,圆角、圆形等处理。
- 自动帮我们缓存图片。内存和磁盘缓存
3. 基本使用
以Android Studio为开发环境,以Gradle为构建工具,其他的本文不做介绍。
3.1 添加依赖
1 | compile 'com.squareup.picasso:picasso:2.5.2' |
3.2 混淆
1 | -dontwarn com.squareup.okhttp.** |
3.3 加载图片
1 | /* 网络图片 */ |
3.3.1 Picasso.with(Context context)
1 | /** |
构造一个默认的Picasso单例,如果注释中的一些基本配置需求无法满足你,你可以使用Picasso.Builder来构造自己的Picasso实例。
3.3.2 load()
很显然,四个load方法,不同的入参,相同类型的返回值。针对不同的图片来源,执行不同的加载方式。
1 | /** |
每一个load()方法都是创建一个RequestCreator实例,load(File file)和load(String path)最后都是通过转换成load(Uri uri)的方式实现加载。而RequestCreator的构造方法中三个参数,第一个是Picasso实例,一个是uri,一个是resourceId,通过后两个参数覆盖所有的加载场景。
1 | RequestCreator(Picasso picasso, Uri uri, int resourceId) { |
3.3.3 into()
RequestCreator中很多方法都是我们经常会用到的。先看into()方法
1 | /** |
可以看到5个into()方法,可以看到Picasso常用的是直接往ImageView,但是它的功能远远不止如此,我们可以通过实现Target接口来实现自定义的图片处理,可以用来设背景,可以用来填充布局,可扩展性很强,也支持RemoteView。而我们常用的
1 | public void into(ImageView target) { |
转到有Callback的执行方法。我们可以通过使用带有回调的into方法来执行图片加载成功或者失败后的事件处理。
1 | public interface Callback { |
看下public void into(ImageView target, Callback callback)这个方法:
- checkMain() 判断是否为主进程
- 非空检查。判断target是否为空,uri 或者 resourceId是否为空;
- deferred是否为true。这个和是否调用fit方法有关。由于fit方法是让图片适应ImageView的大小,所以需要ImageView大小明确之后才执行请求,所以需要延迟执行。
- 创建Request和requestKey
- 是否在Cache查找该图片,通过requestKey,这个Key的构建过程和很多内容有关系。
- 设置占位图片
- 构建Action并提交
以上就是图片加载的主要过程。
4. 进阶用法(链式使用)
主要介绍一下Picasso的其他用法
4.1 noPlaceholder()
不设置占位图片,不能于placeHolder同时使用
1 | /** |
4.2 placeholder()
设置占位图片
1 | /** |
4.3 error()
设置加载出错时的图片
1 | /** An error drawable to be used if the request image could not be loaded. */ |
4.4 tag()
设置tag,方便后续pause,cancel,或者resume。这个应该用的比较少,有可能通过tag来cancel一下。
1 | /** |
4.5 fit() & unfit()
调整图片大小来适配target的边界,这个会导致图片的加载过程在ImageView布局确定之后进行。
1 | /** |
4.6 resizeDimen() & resize()
调整图片大小。
1 | /** Resize the image to the specified dimension size. */ |
4.7 centerCrop() & centerInside()
centerCrop:充满ImageView居中裁剪
centerInside: 完整显示图片但是可能无法充满ImageView
1 | /** |
4.8 onlyScaleDown()
当调用了resize 方法重新设置图片尺寸的时候,调用onlyScaleDown 方法,只有当原始图片的尺寸大于我们指定的尺寸时,resize才起作用。
1 | /** |
4.9 rotate()
旋转图片角度,可指定旋转中心点
1 | /** Rotate the image by the specified degrees. */ |
4.10 config()
设置图片Bitmap格式,如
ALPHA_8,ARGB_4444,ARGB_8888,HARDWARE,RGBA_F16,RGB_565等等。
1 | /** |
4.11 stableKey()
设置固定Key
1 | /** |
4.12 priority()
设置优先级,这个对图片请求的执行顺序有影响,默认的优先级均为NORMAL
1 | /** |
4.13 transform()
添加自定义Transformation,方便执行图形转换。
更多transformation请移步picasso-transformations
1 | /** |
4.14 memoryPolicy()
指定memoryPolicy。NO_CACHE,NO_STORE
NO_CACHE:表示处理请求的时候跳过检查内存缓存
NO_STORE: 表示请求成功之后,结果不存到内存。
1 | /** |
4.15 networkPolicy()
指定NetworkPolicy。NO_CACHE,NO_STORE,OFFLINE
NO_CACHE: 表示处理请求的时候跳过处理磁盘缓存
NO_STORE: 表示请求成功后,结果不缓存到Disk。
OFFLINE: 强制这次请求从缓存中获取结果,不会发起网络请求,不管缓存中能否获取到结果。
1 | /** |
4.16 noFade()
去掉默认的图片加载过程中的渐入效果
1 | /** Disable brief fade in of images loaded from the disk cache or network. */ |
5. 其他用法
5.1 get()
同步方法,获取Bitmap。所以不要在主线程执行此操作
用法:
1 | try { |
源码实现:
1 | /** |
5.2 fetch()
毫无结果的获取图片,也没有目标,也没有返回bitmap,难道只是为了暖场?考虑到Picasso有缓存机制,这个方法还是有一点价值的,提前加载放到缓存,后面加载速度会更快。
1 | /** |
6. 自定义Picasso
默认使用Picasso.with(context)可以快速的构建Picasso实例,但是Picasso支持扩展自定义Picasso,也就是一些默认的配置,我们可以自己来调控。
可以看到Picasso.Builder方法存在很多可配置的内容,downloader, executor, memoryCache,listener等等都是可以自己设置的,配置完成后调用
builder()方法即可返回Picasso实例。
还可以通过如下方法设置全局Picasso实例。
1 | /** |
7. 类图
请适当放大后查看。
8. 主要流程图
请适当放大后查看。