Skip to content

Latest commit

 

History

History
264 lines (186 loc) · 11.3 KB

图片加载库比较.md

File metadata and controls

264 lines (186 loc) · 11.3 KB

图片加载库比较

Android开发过程中,图片加载基本是每个项目都必备的功能,图片加载的开源项目也比较多,从最老牌的Android-Universal-Image-Loader,到后来GoogleVolley再到良心公司SquarePicasso以及FaceBookFrescoGoogle IO开发者大会上推荐的Glide

面对这么多的加载库我们该如何去选择? 他们各有优缺点,没法绝对的来说哪个是最好的,只有根据自己的需要来选择最适合自己的,接下来我们就重点分析下这几个项目的优缺点。

Android Universal Image Loader

最老牌的图片加载库,提供了丰富的配置,简单易用,但是从2015.11开始就已经停止维护了,在当前信息技术高速发展的时代,停止维护我们就只能放弃了。 但是不得不说,他是一个很优秀的项目。

Glide

Maven Central

Image

优点:

  • 支持Gif图片。
  • 支持WebP
  • 加载速度快、流畅度高。
  • Glidewith()方法不光接受Context,还接受ActivityFragment,这样图片加载会和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,减小系统回收压力

默认情况下GlidePicasso加载同样图片的内存占用比:

Image

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

Image

With()方法的比较:

Image

缺点:

  • 体积相对来说比较大,目前最新版的大小在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进行比较。

Maven Central

Image

优点:

  • 体积更小,方法数也更少,更轻量。他的库大小及方法数基本是Glide的四分之一,目前为120k左右
  • 支持WebP
  • 当我们从远程URL地址下载图片时,Picasso相比Glide要快很多。可能的原因是Picasso下载完图片后直接将整个图片加载进内存,而Glide还需要针对每个ImageView的大小来适配压缩下载到的图片,这个过程需要耗费一定的时间。(当然我们可以使用thumbnail()来减少压缩的时间)

缺点:

  • PicassoGlide在磁盘缓存策略上有很大的不同。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推出,自带光环。

Maven Central

Image

  • Fresco中设计有一个叫做Image Pipeline的模块。它负责从网络,从本地文件系统,本地资源加载图片。为了最大限度节省空间和CPU时间,它含有3级缓存设计(2级内存,1级磁盘)。
  • Fresco中设计有一个叫做Drawees模块,它会在图片加载完成前显示占位图,加载成功后自动替换为目标图片。当图片不再显示在屏幕上时,它会及时地释放内存和空间占用。
  • 如果仅用基本的图片加载功能的话,大小仅为20k左右
  • 解压后的图片,即Android中的Bitmap,占用大量的内存。大的内存占用势必引发更加频繁的GC。在5.0以下,GC将会显著地引发界面卡顿。 在5.0以下系统,Fresco将图片放到一个特别的内存区域。当然,在图片不显示的时候,占用的内存会自动被释放。这会使得APP更加流畅,减少因图片内存占用而引发的OOMFresco在低端机器上表现一样出色,你再也不用因图片内存占用而思前想后。
  • 渐进式的JPEG图片格式已经流行数年了,渐进式图片格式先呈现大致的图片轮廓,然后随着图片下载的继续,呈现逐渐清晰的图片,这对于移动设备,尤其是慢网络有极大的利好,可带来更好的用户体验。 Android本身的图片库不支持此格式,但是Fresco支持。使用时,和往常一样,仅仅需要提供一个图片的URI即可,剩下的事情,Fresco会处理。
  • 图片可以在任意点进行裁剪,而不是中心,即自定义居中焦点。
  • JPEG可以在native进行resize,避免了在缩小图片时的OOM风险。
  • 支持Gif图片。
  • 支持WebP
  • 内存管理,三级缓存设计
  • 图片预览,渐进式显示效果和多图请求
  • 第一次加载和加载缓存速度都比较快
  • 下载失败之后,点击重现下载
  • 自定义占位图,自定义overlay, 或者进度条
  • 先显示一个低解析度的图片,等高清图下载完之后再显示高清图
  • 对于本地图,如有EXIF缩略图,在大图加载完成之前,可先显示缩略图
  • 缩放或者旋转图片
  • FrescoGlide在内存占用上,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是最合适的。

参考内容: