图片加载库比较
Android开发过程中,图片加载基本是每个项目都必备的功能,图片加载的开源项目也比较多,从最老牌的Android-Universal-Image-Loader,到后来Google的Volley再到良心公司Square的Picasso以及FaceBook的Fresco和Google IO开发者大会上推荐的Glide。
面对这么多的加载库我们该如何去选择?
他们各有优缺点,没法绝对的来说哪个是最好的,只有根据自己的需要来选择最适合自己的,接下来我们就重点分析下这几个项目的优缺点。
Android Universal Image Loader
最老牌的图片加载库,提供了丰富的配置,简单易用,但是从2015.11开始就已经停止维护了,在当前信息技术高速发展的时代,停止维护我们就只能放弃了。
但是不得不说,他是一个很优秀的项目。
Glide

优点:
- 支持
Gif图片。 - 支持
WebP。 - 加载速度快、流畅度高。
Glide的with()方法不光接受Context,还接受Activity和Fragment,这样图片加载会和Activity/Fragment的生命周期保持一致,比如Pause状态在暂停加载,在Resume的时候又自动重新加载。- 支持设置图片加载优先级。
- 支持缩略图,可以在同一时间加载多张图片到同一个
ImageView中,例如可以首先加载只有ImageView十分之一大小的缩略图,然后等再加载完整大小的图片后会再显示到该ImageView上。 - 内存占用低,
Glide默认的Bitmap格式是RGB_565,比ARGB_8888格式的内存开销要小一半,所以图片质量会稍微差一些,当然这些配置都是可以修改的。 Glide缓存的图片大小是根据ImageView尺寸来缓存的的。这种方式优点是加载显示非常快。且可以设置缓存图片的尺寸- 默认使用
HttpUrlConnection下载图片,可以配置为OkHttp或者Volley下载,也可以自定义下载方式。 - 默认使用两个线程池来分别执行读取缓存和下载任务,且可以自定义。
- 默认使用手机内置存储进行磁盘缓存,可以配置为外部存储,可以配置缓存大小,图片池大小。
- 在加载同样配置的图片时,
Glide内存占用更少,因为Glide是针对每个ImageView适配图片大小后再存储到磁盘的,这样加载进内存的是压缩过的图片,内存占用自然就比较少。这种做法有助于减少OutOfMemoryError的出现。 - 高效处理
Bitmap,使用Bitmap Pool来对Bitmap进行复用,主动调用recycle回收需要回收的Bitmap,减小系统回收压力
默认情况下Glide与Picasso加载同样图片的内存占用比:

配置为ARGB_8888的情况下Glide与Picasso加载同样图片的内存占用比:

With()方法的比较:

缺点:
- 体积相对来说比较大,目前最新版的大小在
500k左右 - 当我们从远程
URL地址下载图片时,Picasso相比Glide要快很多。可能的原因是Picasso下载完图片后直接将整个图片加载进内存,而Glide还需要针对每个ImageView的大小来适配压缩下载到的图片,这个过程需要耗费一定的时间。(当然我们可以使用thumbnail()来减少压缩的时间)
使用简单:
repositories {
mavenCentral()
maven { url 'https://maven.google.com' }
}
dependencies {
compile 'com.github.bumptech.glide:glide:4.1.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
}
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
GlideApp.with(this).load("http://goo.gl/gEgYUd").into(imageView);
Picasso
由良心公司Square开源的一款图片加载库。其实他和Glide很相似,所以一般会与Glide进行比较。

优点:
- 体积更小,方法数也更少,更轻量。他的库大小及方法数基本是
Glide的四分之一,目前为120k左右 - 支持
WebP - 当我们从远程
URL地址下载图片时,Picasso相比Glide要快很多。可能的原因是Picasso下载完图片后直接将整个图片加载进内存,而Glide还需要针对每个ImageView的大小来适配压缩下载到的图片,这个过程需要耗费一定的时间。(当然我们可以使用thumbnail()来减少压缩的时间)
缺点:
Picasso和Glide在磁盘缓存策略上有很大的不同。Picasso缓存的是全尺寸的,而Glide缓存的是跟ImageView尺寸相同的。Glide的这种方式优点是加载显示非常快。而Picasso的方式则因为需要在显示之前重新调整大小而导致一些延迟.- 相对
Glide来说更耗内存,尤其是加载大一点的图片。同样是因为上面的缓存策略不同。 - 不支持
Gif图片
使用:
// 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);
- 修改图片大小
// Picasso
.resize(300, 200);
// Glide
.override(300, 200);
- 图片裁剪
// Picasso
.centerCrop();
// Glide
.centerCrop();
- 设置占位图及错误图片
// Picasso
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)
// Glide
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)
Fresco
由Facebook推出,自带光环。

Fresco中设计有一个叫做Image Pipeline的模块。它负责从网络,从本地文件系统,本地资源加载图片。为了最大限度节省空间和CPU时间,它含有3级缓存设计(2级内存,1级磁盘)。Fresco中设计有一个叫做Drawees模块,它会在图片加载完成前显示占位图,加载成功后自动替换为目标图片。当图片不再显示在屏幕上时,它会及时地释放内存和空间占用。- 如果仅用基本的图片加载功能的话,大小仅为
20k左右 - 解压后的图片,即
Android中的Bitmap,占用大量的内存。大的内存占用势必引发更加频繁的GC。在5.0以下,GC将会显著地引发界面卡顿。
在5.0以下系统,Fresco将图片放到一个特别的内存区域。当然,在图片不显示的时候,占用的内存会自动被释放。这会使得APP更加流畅,减少因图片内存占用而引发的OOM。
Fresco在低端机器上表现一样出色,你再也不用因图片内存占用而思前想后。 - 渐进式的
JPEG图片格式已经流行数年了,渐进式图片格式先呈现大致的图片轮廓,然后随着图片下载的继续,呈现逐渐清晰的图片,这对于移动设备,尤其是慢网络有极大的利好,可带来更好的用户体验。
Android本身的图片库不支持此格式,但是Fresco支持。使用时,和往常一样,仅仅需要提供一个图片的URI即可,剩下的事情,Fresco会处理。 - 图片可以在任意点进行裁剪,而不是中心,即自定义居中焦点。
JPEG可以在native进行resize,避免了在缩小图片时的OOM风险。- 支持
Gif图片。 - 支持
WebP。 - 内存管理,三级缓存设计
- 图片预览,渐进式显示效果和多图请求
- 第一次加载和加载缓存速度都比较快
- 下载失败之后,点击重现下载
- 自定义占位图,自定义
overlay, 或者进度条 - 先显示一个低解析度的图片,等高清图下载完之后再显示高清图
- 对于本地图,如有EXIF缩略图,在大图加载完成之前,可先显示缩略图
- 缩放或者旋转图片
Fresco和Glide在内存占用上,Fresco更优,这是由于Fresco将图片放置到一块特殊的Native内存,这块内存的管理是由Fresco进行的,所以Fresco的体积比较庞大,会为应用增加接近2M的体积,这算是Fresco的一个缺点.
缺点:
- 他也是一个非常优秀的项目,由于
Fresco的设计需要使用DraweeView替代ImageView所以我个人来说没有选择它, - 由于其缓存特性,会导致应用的体积变大。
使用:
- 必备功能
dependencies {
// your app's other dependencies
compile 'com.facebook.fresco:fresco:1.5.0'
}
- 可选功能
dependencies {
// For animated GIF support
compile 'com.facebook.fresco:animated-gif:1.5.0'
// For WebP support, including animated WebP
compile 'com.facebook.fresco:animated-webp:1.5.0'
compile 'com.facebook.fresco:webpsupport:1.5.0'
// For WebP support, without animations
compile 'com.facebook.fresco:webpsupport:1.5.0'
// Provide the Android support library (you might already have this or a similar dependency)
compile 'com.android.support:support-core-utils:24.2.1'
}
- 初始化:
[MyApplication.java]
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Fresco.initialize(this);
}
}
- 创建布局文件:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="130dp"
android:layout_height="130dp"
fresco:placeholderImage="@drawable/my_drawable"
/>
</LinearLayout>
- 代码使用:
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/master/docs/static/logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);
综上所述:对我来说Glide是最合适的。
参考内容:
你的star是我的动力!!!

本文对比分析了Android中流行的图片加载库,包括Glide、Picasso、Fresco等,从体积、性能、缓存策略等方面进行了详细说明,帮助开发者根据项目需求选择最适合的图片加载方案。



4668

被折叠的 条评论
为什么被折叠?



