一、与 Glide 库对比
Picasso 和 Glide 是两款流行的 Android 第三方图片加载库,它们在功能、性能、易用性等方面各有特点,以下是它们的主要区别:
1、 缓存策略
- Picasso:采用两级缓存机制(内存缓存和磁盘缓存),仅缓存图片的原始尺寸。当需要不同尺寸的图片时,需要重新解码,可能会增加内存占用。
- Glide:采用三级缓存机制(内存缓存、磁盘缓存和网络缓存),并且会缓存不同尺寸的图片。这种策略可以减少重复解码,提高加载效率。
2、 动态图支持
- Picasso:不支持 GIF 动态图,只能显示 GIF 的第一帧。
- Glide:原生支持 GIF、WebP 和 APNG 等动态图片格式,并且加载时不需要额外配置。
3、 生命周期管理
- Picasso:需要开发者手动管理图片加载的生命周期。
- Glide:支持与 Activity 或 Fragment 生命周期绑定,自动暂停和恢复图片加载。例如,在 Activity 的 Paused 状态暂停加载,在 Resumed 状态自动恢复。
4、 图片变换
- Picasso:支持基本的图片变换,但需要依赖额外的库(如 Transformation 库)。
- Glide:内置了丰富的图片变换功能(如圆角、灰度等),并且支持自定义变换。
5、 性能
- Picasso:内存占用较小,电池消耗较低,适合对性能要求不高且注重轻量级的项目。
- Glide:内存占用相对较多,电池消耗较高,但在处理大型图片和复杂变换时表现更优。
6、 库大小和方法数
- Picasso:库大小约为 118 KB,方法数约为 849,适合小型项目。
- Glide:库大小约为 440 KB,方法数约为 2678,适合功能复杂、需要丰富图片处理能力的项目。
7、 易用性
- Picasso:API 简洁易用,适合新手快速上手。
- Glide:API 功能强大但相对复杂,需要一定的学习成本。
8、 其他功能
- Picasso:支持自定义图片加载的回调方法。
- Glide:支持加载视频缩略图,并且可以自定义网络栈。
9、总结
- 如果项目对图片加载需求简单,注重易用性和轻量级,可以选择 Picasso。
- 如果项目需要处理动态图片、复杂变换或大量图片,且对性能要求较高,可以选择 Glide。
二、Picasso 使用前配置
1、添加依赖库
- 在模块的 build.gradle 文件中添加以下依赖:
dependencies {
......
// Picasso
implementation("com.squareup.picasso:picasso:2.8")
}
2、添加网络权限
- 如果需要加载网络图片,则需要先在 AndroidManifest.xml 中增加网络权限。
<uses-permission android:name="android.permission.INTERNET"/>
三、Picasso 方法介绍
1、加载图像:
- load(String path):从指定路径加载图像,可以是本地文件路径或网络URL。
- load(File file):从文件加载图像。
- load(Uri uri):从Uri加载图像。
- load(int resourceId):从资源ID加载图像。
2、图像显示:
- into(ImageView imageView):将图像显示到指定的ImageView中。
- into(Target target):将图像显示到自定义的Target对象中,可以用于处理图像的进一步操作。
- into(BitmapTarget target):将图像显示到自定义的BitmapTarget对象中,可以获取Bitmap对象进行进一步处理。
3、图像处理:
- resize(int width, int height):调整图像大小,单位像素值。
- resizeDimen(int targetWidthResId, int targetHeightResId):调整图像大小,单位dp值。
- centerCrop():居中裁剪图像以适应ImageView的尺寸。
- fit():按比例缩放图像,使其完全适应ImageView的尺寸。
- rotate(float degrees):旋转图像指定角度。
- transform(Transformation transformation):应用自定义的图像转换器。
4、图像占位符和错误处理:
- placeholder(int resourceId):在加载图像之前显示的占位符。
- error(int resourceId):加载图像失败时显示的错误占位符。
- noFade():
Picasso 从磁盘或者网络加载图片时,into 显示到ImageView 都会有一个简单的渐入过度效果,让你的UI视觉效果更柔顺丝滑一点,如果你不要这个渐入的效果,就调用noFade方法。
5、缓存控制:
- memoryPolicy(MemoryPolicy memoryPolicy):设置内存缓存策略。
- networkPolicy(NetworkPolicy networkPolicy):设置网络缓存策略。
6、清除缓存:
- invalidate(String path):使指定路径的图像缓存失效。
- clearMemory():清除内存缓存。
- clearDiskCache():清除磁盘缓存。
7、Tag 管理请求
- cancelTag(Object tag) :取消设置了给定tag的所有请求。
- pauseTag(Object tag) :暂停设置了给定tag 的所有请求。
- resumeTag(Object tag) :resume 被暂停的给定tag的所有请求。
- tag(Object tag) :为请求设置tag。
四、Picasso 使用场景
1、加载图片
- Picasso 除了可以加载网络图片,还支持加载文件图片,加载本地资源图片,加载一个Uri 路径的图片。
- load(String path) 方法接受String 参数,参数 String 可以是一个网络图片 url,也可以是file 路径、content资源 和Android Resource。除了网络 url,其它几种需要加上对应前缀,file 文件路径前缀:file: , content 添加前缀:content: ,Android Resource 添加:android.resource:
// 加载网络图片
val url = "https://fastly.picsum.photos/id/54/200/200.jpg?hmac=-2_HX5umbAEVPP9CokmPW3Kc8V9iDplneKlS73LWdQQ"
Picasso.get()
.load(url)
.into(imageView)
// 加载本地资源图片
Picasso.get()
.load(R.mipmap.weather_sun)
.into(imageView)
// 加载本地文件图片
val filePath = "$filesDir/weather_sun.png"
Picasso.get()
.load(File(filePath))
.into(imageView)
2、指定图片大小
- 如果图片过大,可能会导致内存问题,建议在加载时指定目标大小。
- 当调用了resize 方法重新设置图片尺寸的时候,调用onlyScaleDown 方法,只有当原始图片的尺寸大于我们指定的尺寸时,resize才起作用。
val url = "https://fastly.picsum.photos/id/54/200/200.jpg?hmac=-2_HX5umbAEVPP9CokmPW3Kc8V9iDplneKlS73LWdQQ"
// 像素值
Picasso.get()
.load(url)
.resize(100, 100)
.onlyScaleDown()
.into(imageView)
// dp 值
Picasso.get()
.load(url)
.resizeDimen(R.dimen.dp_100, R.dimen.dp_100)
.onlyScaleDown()
.into(imageView)
3、设置占位图和错误图
- placeholder 方法提供一张在网络请求还没有完成时显示的图片,它必须是本地图片。
- error 方法提供一张在加载图片出错的情况下显示的默认图。
- 从加载图片到显示到 View 中有一个简单的渐入过度效果,调用 noFade 方法可以取消这个渐入效果。
val url = "https://fastly.picsum.photos/id/54/200/200.jpg?hmac=-2_HX5umbAEVPP9CokmPW3Kc8V9iDplneKlS73LWdQQ"
Picasso.get()
.load(url)
.placeholder(R.mipmap.weather_sun) // 加载中显示的图片
.error(R.mipmap.ic_launcher) // 加载失败显示的图片
.noFade()
.into(imageView)
4、图片裁剪
- 当使用resize 来重新设置图片的尺寸时,会发现有些图片拉伸或者扭曲了,要避免这种情况,可以调用 centerCrop 方法,使图像充满 View 的边界,居中裁剪。
- centerCrop 是可能看不到全部图片的,如果想完全展示图片,可以调用 centerInside 方法,但是如果图片尺寸小于 View 尺寸的话,是不能充满 View 边界的。
- fit 方法会自动测量 View 的大小,然后内部调用reszie 方法把图片裁剪到 View 的大小,实际做了计算 size 和调用 resize 2步动作,非常方便。**
- 使用 fit 方法还是会出现拉伸扭曲的情况,因此最好配合前面的 centerCrop 使用
- fit 方法只对 ImageView 有效,使用 fit 时,ImageView 宽和高不能为wrap_content,因为它要测量宽高。
- 调用 fit 方法时,不能同时调用 resize 方法。必须调用 resize 方法后才能调用 centerCrop 方法,不能单独调用 centerCrop 方法。
val url = "https://fastly.picsum.photos/id/54/200/200.jpg?hmac=-2_HX5umbAEVPP9CokmPW3Kc8V9iDplneKlS73LWdQQ"
Picasso.get