A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大山哥哥 于 2017-2-27 16:01 编辑

说到安卓中的图片加载框架,大家可能第一时间就能想到Universal-Image-Loader、Fresco、Glide和Picasso等。在这里面,Glide和Picasso在使用的时候相似度还非常高。今天我们就来研究一下Glide和Picasso这两个图片加载框架,看一看他们的异同以及如何选择适合自己的框架。

        谷歌为我们介绍了一个名叫Glide的图片加载库,作者是bumptech。这个库被广泛的运用在google的开源项目中,包括2014年google I/O大会上发布的官方app。
Glide和Picasso有90%的相似度,准确的说,就是Picasso的克隆版本,但是在细节上还是有不少区别的。
        依赖方面,Picasso是独立依赖,配置的时候直接在gradle脚本中添加compile 'com.squareup.picasso:picasso:x.x.x',而Glide除了添加compile 'com.github.bumptech.glide:glide:x.x.x'之外,还需要添加v4包的依赖,不过现在来说几乎没有哪个应用是不添加v4的依赖了,所以这一块也几乎没什么影响。
        首先我们从应用方式入手,看一下基本的使用语法:
Picasso
[AppleScript] 纯文本查看 复制代码
Picasso.with(context)
    .load("http://host.aaa.bbb/ccc.jpg")
    .into(mImageView);
Glide
[AppleScript] 纯文本查看 复制代码
Glide.with(context)
.load("http://host.aaa.bbb/ccc.jpg")
.into(mImageView);
        可以看出,加载图片的时候,两者的使用方式如出一辙。但是这里需要注意一个小细节:Glide的with方法不光接受Context,还接受Activity 和 Fragment,Context会自动的从他们获取。同时,将Activity/Fragment作为with()参数的好处是:图片加载会和Activity/Fragment的生命周期保持一致,比如 Paused状态在暂停加载,在Resumed的时候又自动重新加载。所以我建议传参的时候传递Activity 和 Fragment给Glide,而不是Context。所以从细节上来说,Glide做的更完美一些。
        然后我们来分析一下两者在加载时的内存占用。Glide默认的Bitmap格式是RGB_565 ,比PicassoARGB_8888格式的内存开销要小一半,不过同时带来的问题就是图片质量的降低(必然的,质量越高需要的内存越大),所以如果是对图片质量要求更高的使用场景,使用默认配置就不符合我们想需求了。不过我们可以通过修改GlideModule的方式修改默认的配置,代码如下:
        首先,在代码中添加如下配置,修改图片质量为ARGB_8888。
[AppleScript] 纯文本查看 复制代码
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.
    }
}
        然后,在AndroidManifest.xml中将GlideModule定义为meta-data即可生效。
[AppleScript] 纯文本查看 复制代码
<meta-data android:name="你的包名.GlideConfiguration"
android:value="GlideModule"/>
        上述方式虽然能修改图片质量,但是内存占用相应的就上升了很多,不过内存的占用还是比Picasso要少很多。这又是为什么呢?原因是Picasso是加载原尺寸的图片到内存,然后计算出合适的大小设置到ImageView上;而Glide是根据ImageView的大小去加载相同大小的图片,所以在加载之前就把尺寸的问题解决了,从而节省了内存开销。当然,Picasso也可以指定加载的图片大小的,只不过需要额外做一个配置:
[AppleScript] 纯文本查看 复制代码
Picasso.with(this)
.load("http://host.aaa.bbb/ccc.jpg")
    .resize(768, 432)
.into(mImageView);
或者
Picasso.with(this)
.load("http://host.aaa.bbb/ccc.jpg")
.fit()
.centerCrop()
.into(mImageView);

        接下来是磁盘缓存方面,在磁盘缓存的处理方式上,Glide和Picasso也是选择了不同的解决方案:Glide是缓存了跟ImageView大小一致的图片缓存,而Picasso是缓存了原尺寸的图。在这一点上,如果下一次ImageView的大小发生了改变,Picasso不会重新缓存图片,而对于每一个尺寸的ImageView,Glide都会重新下载图片,然后创建一个尺寸一致的缓存。具体说来就是:假如在第一个页面有一个200x200的ImageView,在第二个页面有一个100x100的ImageView,这两个ImageView本来是要显示同一张图片,却需要下载两次。
        不过,你可以改变这种行为,让Glide既缓存全尺寸又缓存其他尺寸,从而减少下载的次数:
[AppleScript] 纯文本查看 复制代码
Glide.with(this)
     .load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
     .diskCacheStrategy(DiskCacheStrategy.ALL)
     .into(ivImgGlide);
        下次在任何ImageView中加载图片的时候,全尺寸的图片将从缓存中取出,重新调整大小,然后缓存。Glide的这种方式优点是加载显示非常快。而Picasso的方式则因为需要在显示之前重新调整大小而导致一些延迟。所以从速度上来说,Glide更快,不过,这个快是建立在创建了更多缓存的基础上的,所以空间和时间自己选一个吧。
        最后,祭出一个大杀器,Glide可以加载GIF动图,而Picasso则很遗憾的只能加载第一帧的静态图片。同时因为Glide和Activity/Fragment的生命周期是一致的,因此gif的动画也会自动的随着Activity/Fragment的状态暂停、重放。Glide 的缓存在gif这里也是一样,调整大小然后缓存。不过使用Glide加载动图需要格外小心,因为这个特性使Glide非常消耗内存。
        总之,Glide和Picasso都是非常完美的图片加载框架,而且经过配置的话,达到的效果更是非常类似。整体上说,Picasso的图片质量更佳,而Glide的加载速度更快,并且何以加载GIF图片。个人比较推荐Glide,因为用户的体验第一,速度才是王道,更不用说安卓的谷歌爸爸也大量的使用Glide作为图片加载的框架了。



3 个回复

倒序浏览
大山哥哥好腻害!
回复 使用道具 举报
不错,长知识了,赞一下
回复 使用道具 举报
多谢分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马