图片加载框架Picasso和Glide

引言

前面我们已经讲解了老牌图片加载框架Universal-Image-Loader,讲解了它的使用,并分别从图片三级缓存的角度和缓存Lru算法角度详细分析了源码,还给大家做出了总结,不清楚的可以去 安卓面试系列–Universal-Image-Loader图片加载框架和 安卓面试系列–OOM异常(二)这两篇博客中看看。今天我们来讲另外两个图片加载框架,Picasso和Glide,这两者非常像,所以我们放在一起讲。

导入库

Picasso:

compile 'com.squareup.picasso:picasso:2.5.1'

Glide:

compile 'com.github.bumptech.glide:glide:3.5.2'

基本使用

Picasso:

Picasso.with(context)
    .load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
    .into(ivImg);

Glide:

Glide.with(context)
    .load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
    .into(ivImg);

虽然两者看起来一样,但是Glide更易用,因为Glide的with方法不光接受Context,还接受Activity 和 Fragment,Context会自动的从他们获取。

图片加载框架Picasso和Glide_第1张图片

将Activity或者Fragment作为with()的参数的好处是:图片加载会和Activity/Fragment的生命周期保持一致。比如在pause状态停止加载,在resume状态重新加载。所以建议把activity或者fragment作为参数传递给Glide,而不是Context。

内存缓存

Glide加载图片默认使用的是RGB_565,占用两个字节,而Picasso加载图片默认是加载完整的图,使用的是ARGB_8888,占用四个字节,所以,使用Glide消耗的内存比Picasso小一半,这也是Glide的一大优势所在。
这是把一张1920x1080 像素的图片加载到768x432的ImageView中,两者的内存开销对比图:

图片加载框架Picasso和Glide_第2张图片

当然也不是说Glide不可以使用ARGB_8888格式加载图片,如果需要的话,可以新建一个GlideModule,然后在applyOptions中设置解码格式:

public class GlideConfiguration implements GlideModule {

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // Apply options to the builder here.
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        // register ModelLoaders here.
    }
}

同时需要在manifest.xml文件中,将GlideModule定义为meta-data:

"com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
            android:value="GlideModule"/>

这个时候再来看一下内存开销对比图:
图片加载框架Picasso和Glide_第3张图片

我们可以发现,Glide花费的内存是上一次的两倍,但还是比Picasso小的多,为什么会这样呢?因为Picasso是把全尺寸的图片加载到内存中去,而Glide只是把和ImageView大小的图片加载到内存中去,所以更小。当然,Picasso也可以指定大小,通过resize()方法指定大小:

Picasso.with(this)
    .load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
    .resize(768, 432)
    .into(ivImgPicasso);

如果指定大小的话,那么你就需要准确的知道你的ImageView控件的大小,这可能会需要用到计算。但是你也可以这样:

Picasso.with(this)
    .load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
    .fit()
    .centerCrop()
    .into(ivImgPicasso);

这样也可以实现加载控件大小的图片到内存。

图片加载框架Picasso和Glide_第4张图片

这样Picasso的内存开销就和Glide差不多了。但是是不是比Glide麻烦多了,所以,在内存方面,Glide完胜。

磁盘缓存

Picasso和Glide在磁盘缓存上的策略大不相同。Picasso是缓存全尺寸到内存,而Glide则缓存和ImageView大小相同的尺寸到内存。

我们通过改变ImageView的尺寸来尝试分析两者缓存的不同,测试后发现,不管ImageView有多大,Picasso都只缓存一张全尺寸的图片到内存,而Glide则不同,每次都会缓存一张跟ImageView一样大的图片。假如我们继续改变ImageView的尺寸,Glide会重新下载这张图片,然后调整大小并缓存起来。

图片加载框架Picasso和Glide_第5张图片

举个栗子:假如第一个页面是一个200*200的ImageView,第二个页面是100*100的ImageView,而这两个ImageView要显示的是一张图片,但是却要下载两次。

不过,我们通过以下设置,让Glide也缓存全尺寸的图片。

Glide.with(this)
     .load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
     .diskCacheStrategy(DiskCacheStrategy.ALL)
     .into(ivImgGlide);

这样,下次不管ImageView有多大,我们都会把全尺寸的图片从缓存中取出来,然后调整大小并显示到ImageView上,并把这个尺寸的图片缓存起来,也就是说少了一次下载的过程。

Glide的这种方式的优点就是加载速度非常快,而Picasso则需要在显示之前重新调整大小而导致延时。

其他特性

Glide可以做到和Picasso一样多的事情,代码量也不会增加太多。

指定图片的大小

// Picasso
.resize(300, 200);

// Glide
.override(300, 200);

Center Cropping

// Picasso
.centerCrop();

// Glide
.centerCrop();

图形转换

// Picasso
.transform(new CircleTransform())

// Glide
.transform(new CircleTransform(context))

设置占位图或者加载错误图

// Picasso
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)

// Glide
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)

那么有什么是Glide独有的特性呢?

Glide可以加载动态图,而Picasso不可以

图片加载框架Picasso和Glide_第6张图片

同时因为Glide和activity或者fragment的生命周期一致,所以gif动画也会随着activity或者fragment的状态暂停、重放。Glide的缓存在gif图中也是一样的,先调整大小然后在缓存。

但是Glide动画消耗的内存太多,需要谨慎使用。

除了可以加载gif动画,Glide还可以将本地视频解码成一张静态图片。

Glide还可以配置显示图片的动画,而Picasso只有fading in。

总结

  • Glide和Picasso它们的功能很类似,都是通过with(context).load(url).into(ImageView)的方式来加载图片,但是Glide可以将activity或者fragment作为上下文传递给with,这样就可以让图片加载的过程和activity或者fragment的生命周期保持一致。
  • 内存缓存上:
    • 同时使用Glide的内存开销比Picasso小,因为,Glide默认是使用RGB_565格式来显示图片,而Picasso则是默认ARGB_8888格式,所以它显示的图片质量会更高,但是更消耗内存。
    • Picasso加载了全尺寸的图片到内存,并且让GPU实时重绘,而Glide则是加载和ImageView大小一致的图片到内存。
  • 在硬盘缓存上,Picasso缓存全尺寸的图片,所以需要在显示之前重新调整大小,会导致延迟。而Glide则缓存和ImageView尺寸相同的图片,并且同一张图会缓存多个尺寸,所以加载速度会比Picasso快。但是这样的话,Glide就需要更大的空间来缓存图片了。可以理解为Glide通过增加空间的代价来换取时间上的优势。
  • 另外,Glide可以做到Picasso的几乎任何事,比如调整图片大小、设置占位图和错误图等等,而Glide最大的优势是可以加载动态图,但是加载动态图的内存开销会非常大。还有一些零零散散的特性,比如本地视频转静态图片、图片显示的多种动画等等。

你可能感兴趣的:(android基础)