Android 进阶之第三方库的介绍 Picasso
Picasso是什么?
它是一个图片的加载和缓存库,它能以最简单的方式来加载一张图片,目前最新的版本为2.5.2我们可以到如下的官网下载最新的jar包,或者在Android studio 在module build.gradle配置文件中加入如下的配置:
Picasso 官网
compile 'com.squareup.picasso:picasso:2.5.2' |
Picasso的用法十分简单,并且不仅仅能加载网络资源,也能加载本地图片,Android资源文件,以及使用URI地址对图片进行加载。
创建Picasso实例:
- 标准的Picasso实例
创建Picasso实例的最简单方法就是调用它的with方法并传入对应的context.这时候创建的是标准的Picasso对象。
如下所示:Picasso.with(context)
- 自定义Picasso实例
但是有时候标准的Picasso对象并不能满足我们特定情形的要求,所以就需要使用 Picasso.Builder:
Picasso.Builder customPicassoBuilder = new Picasso.Builder(context); |
- 如何将自定义的Picasso作为全局使用的Picasso:
这里需要注意的是如果在创建Picasso的时候Picasso已经被设置过这时出现异常,在定义完自定义的Picasso后在在Picasso.with(context)调用之后进行设置也会出现该异常,所以需要添加一个try{ }catch{ }try{
Picasso.Builder picassoBuilder = new Picasso.Builder(context);
Picasso picasso = picassoBuilder.build();
Picasso.setSingletonInstance(picasso);
}catch(IllegalStateException ignored){
}
使用Picasso加载缓存图片:
- 加载Android资源文件:
ImageView imageView = (ImageView) findViewById(R.id.imageView);
int resId = R.mipmap.ic_launcher;
Picasso.with(context).load(resId).into(imageView); - 加载本地文件:
ImageView imageView = (ImageView) findViewById(R.id.imageView);
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "test.png");
Picasso.with(context).load(file).into(imageView); - 加载网络资源:
ImageView imageView = (ImageView) findViewById(R.id.imageView);
String imageUrl = "http://xxxxxxxxxxxxxxxxxxxxxx";
Picasso.with(context).load(imageUrl).into(imageView); - 在ListView中使用:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null){
convertView = View.inflate(context,R.layout.item_picasso,null);
}
ImageView imageView = (ImageView)convertView;
if (TextUtils.isEmpty(imageUrls[position])){
//如果是空uri图片那么取消请求
Picasso.with(context).cancelRequest(imageView);
imageView.setImageDrawable(null);
}else {
//加载图片
Picasso.with(context)
.load(imageUrls[position])
.placeholder(R.mipmap.ic_launcher)//如果没有图片的时候的占位图
.error(R.mipmap.ic_launcher) //发生错误时候的图片
.into((ImageView) convertView);
}
return convertView;
}
一些常见的属性设置:
- 自定义图片大小处理:
ImageView imageView = (ImageView) findViewById(R.id.imageView);
int resId = R.mipmap.ic_launcher;
Picasso.with(context).load(resId).resize(1028, 2000).into(imageView); - onlyScaleDown
如果调用了resize(x,y)来设定图片的大小的话,Picasso一般会重新以改变图片的加载质量,但是如果我们的原图是比我们从新resize的新图规格大的时候,我们就可以调用onlyScaleDown()来直接进行展示而不再重新计算.Picasso
.with(context)
.load(xxxxxxxxxxx)
.resize(6000, 2000)
.onlyScaleDown()
.into(xxxxxxxxx); - 图片的缩放拉伸处理
Picasso提供了两种选择用户处理图片的拉伸处理:
centerCrop() - 图片会被剪切
centerInside()- 图片会被完整的展示,可能图片不会填充满ImageView。
Picasso |
- 图片的旋转处理
当我们对一张图片只需要进行简单的旋转处理时,只需要调用传入大于0小于360的旋转角度即可:
Picasso.with(context) |
除了上述的旋转,还可以为旋转设定一个支点,只需要将上述的rotate换作rotate(float degrees, float pivotX, float pivotY) 即可:
Picasso |
对无效Uri的响应图片:
.placeholder(R.mipmap.ic_launcher)
对访问错误时的响应图片
.error(R.mipmap.error)
不使用默认的淡入的效果,加载的图片直接显示在ImageView上:
Picasso
.with(context)
.load(imageUri)
.noFade() //不使用默认的淡入的效果
.into(imageView);第二次图片进来的时候不使用占位图片noPlaceholder
Picasso
.with(context)
.load(imageUri)
.placeholder(R.mipmap.ic_launcher)
.into(imageView, new Callback() {
@Override
public void onSuccess() {
Picasso
.with(context)
.load(imageUri)
.noPlaceholder()
.into(imageView);
}
@Override
public void onError() {
}
});使用fit 优化减小内存空间占用
使用fit Picasso会对图片的大小及ImageView控件进行测量,计算出最佳的大小及最佳的图片质量以减少内存;Picasso
.with(context)
.load(yyyyyyyyyyyyyy)
.fit()
.into(rrrrrrrrrrrrrr);设置图片加载的优先级
Picasso支持设置优先级,分为HIGH, MEDIUM, 和 LOW,所有的加载默认优先级为MEDIUM,但是这种设置并不能保证图片一定会优先加载,只是会偏向于优先加载,这个和给某个变量声明为regiter是一个道理的
Picasso |
- 使用TAG来处理请求:
在ListView中使用网络图片是很常见的,在我们滑动ListView的时候Picasso是会不断在进行网络请求,取消请求,再次请求,取消请求的状态进行的,这往往会对性能产生严重影响。使用TAG标签,可以在用户在快速滑动的时候全部停止请求,只有在滑动停止时再去请求。
Picasso提供了三种设置Tag的方式
暂停标记 pauseTag() |
用法:
首先为某个Picasso对象添加一个标签:
Picasso |
然后实现滑动监听,在监听中操作Tag
@Override |
cancleTag() 一般在不再需要进行网络请求的时候进行调用,并且在使用TAG的时候要记住如果tag状态为pause或者resume的话,Picasso会对tag持有一个引用,如果没有及时处理当前Activity退出的时候,执行垃圾回收的时候,就会出现内存泄露,所以要注意在onDestory()方法中进行相应处理。以避免这种情况的发生。
- 使用 fetch() .get() .target()
.fetch() 不会返回Bitmap,更不会展现在ImageView上,它只是将数据加载到本地和内存中从而加快后期的加载速度。
.get() 使用get会返回一个Bitmap,但是该方法不能在主线程中调用,因为会造成线程阻塞;
.target() 上面的例子我们都是使用.into()方法,将图片资源加载到ImageView中,除了这种方法还可以使用方法来实现同样的功能:
private Target target = new Target() { |
Picasso |
- 在自定义Notifications上使用Picasso:
使用Picasso可以将图片加载到RemoteViews上,从而可以在锁屏,Widget,以及Notification上使用Picasso。下面是对应的用法:
RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.item_picasso); |
- 对图片进行模糊处理
首先通过实现Transformation 接口来实现一个Transformation
public class BlurByPicasso implements Transformation { |
为其设置效果:
Picasso |
- 对图片进行多种处理
除了对图片进行单种处理外还可以将多个处理应用到Picasso上,这就需要用到transform(List<? extends Transformation> transformations)
````
public class TransformationOne implements Transformation {
private final Picasso picasso;
public TransformationOne(Picasso picasso) {
this.picasso = picasso;
}
@Override
public Bitmap transform(Bitmap source) {
//在这里对图片进行各种转换
return result;
}
@Override
public String key() {
return “TransformationOne”;
}
}
public class TransformationTwo implements Transformation {
private final Picasso picasso;
public TransformationTwo(Picasso picasso) {
this.picasso = picasso;
}
@Override
public Bitmap transform(Bitmap source) {
//在这里对图片进行各种转换
return result;
}
@Override
public String key() {
return “TransformationTwo”;
}
}
接下创建一个Transformation 列表,将上述的转换添加到列表上: |
Picasso
.with(context)
.load(xxxxxxxxxxxxxxxxxx)
.transform(transformations)
.into(imageView);
|
LRU缓存占应用程序可用内存的15%
本地缓存占到硬盘空间的2%但不超过50M并且不小于5M
Picasso默认开启3个线程来进行本地与网络之间的访问
Picasso加载图片顺序, 内存–>本地–>网络
* 存储策略 |
NO_CACHE - 不将图片缓存在内存中
NO_STORE - 这个适用于所加载的图片只加载一次就没用了,这种情况Picasso使用完图片就不会在内存及本地缓存了
Picasso
.with(context)
.load(xxxxxxxxxx)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.into(imageView);
或者:
Picasso
.with(context)
.load(xxxxxxxxxx)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.into(imageView);
|
NO_CACHE - 让Picasso跳过从本地读取资源这一过程
NO_STORE - 让Picasso不进行本地图片缓存
OFFLINE - 让Picasso加载图片的时候只从本地读取,除非联网正常并且本地找不到资源的情况下
``` |
同时memoryPolicy和networkPolicy还可以一起使用:
Picasso |
图片缓存指示器
- 使用图片缓存指示器:
要想知道到底图片来源于何处可以使用setIndicatorsEnabled(true)打开图片来源指示器:使用图片来源指示器后就会在图片的左上角出现一个颜色标记蓝色,绿色,红色;Picasso
.with(context)
.load(xxxxxxxxxx)
.setIndicatorsEnabled(true);蓝色 - 从内存中获取,是最佳性能展示
绿色 - 从本地获取,性能一般
红色 - 从网络加载,性能最差
对应Log信息输出:
- 使用图片加载Log查看图片加载信息:
如果要查看图片加载所用的时间可以使用setLoggingEnabled(true),这时候每张网络请求的资源所用的时间可以以Log的形式输出:如果要对整个图片的加载尺寸等数据进行查看可以使用getSnapshot方法Picasso
.with(context)
.setLoggingEnabled(true);
StatsSnapshot picassosnapStats = Picasso.with(context).getSnapshot(); |