使用Glide Custom ModelLoader加载自定义格式的图片资源

Android Glide是一个开源的图片加载和缓存处理的第三方框架。在得到2014年泰国举行的Google IO大会官方推荐后,被广泛应用在谷歌的官方app里。
关于各种图片加载库的缓存策略,网上资源非常丰富,这里不做搬运。可参考
因为国内Glide资料较少,特此做个记录。

Picasso v/s Imageloader v/s Fresco v/s Glide

那么在众多的图片加载库中,为什么选择Glide?
Universal Image Loader、Picasso(Square出品)、Volley ImageLoader(Google官方出品)、Fresco(Facebook出品)的对比图如下
摘自stackoverflow
对比图

Glide特点

从Glide的官方wiki上,得知Glide有如下特点
Glide官方wiki

  • 支持GIF的加载,支持常见数据格式jpg、png、webp、SVG等,支持多种数据源网络、Resource资源、assets 、File、Uri、字节数组等
  • 支持本地Video缩略图加载
  • 支持原图转换缩略图加载、可设置加载尺寸、加载形式(如圆形图片、拉伸截取中间部分显示、等比拉伸填满等)
  • 支持根据Activity、Fragment、Context的生命周期自动管理请求、可设置请求监听
  • 支持淡入淡出动画加载,自定义动画
  • 支持高效处理加载Bitmap
  • 支持自定义缓存策略、清理缓存
  • 最大的特点,可配置度高,是一个很灵活的图片加载框架,如可自定义数据源获取、中间转换、目标数据,同时专注于平滑滚动的图片加载,速度更快

Glide自定义ModelLoader

由于项目需求,使用获取缩略图的api会根据图片ID输出一个FileOutputstream或Bitmap,需要通过自定义ModelLoader的形式,加载缩略图列表。
即实现 Glide.with(mContext).load(“传入图片ID”).into(ImageView);
参考中的Demo

自定义一个GlideModule来注册ModelLoader

1
2
3
4
5
6
7
8
9
10
11
12
public class CustomGlideModule implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// Apply options to the builder here.
}
@Override
public void registerComponents(Context context, Glide glide) {
// register ModelLoaders here.
glide.register(String.class, Bitmap.class, new PhotoLoader.Factory());
}
}

在AndroidManifest.xml中注册

1
2
3
<meta-data
android:name="com.royole.focus.browser.glide.CustomGlideModule"
android:value="GlideModule" />

混淆处理

1
2
-keepnames com.royole.focus.browser.glide.CustomGlideModule
#-keep public class * implements com.bumptech.glide.module.GlideModule

实现自定义的ModelLoader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class PhotoLoader implements ModelLoader<String, Bitmap> {
public PhotoLoader() {
}
@Override
public DataFetcher<Bitmap> getResourceFetcher(String model, int width, int height) {
return new PhotoFetcher(model);
}
// ModelLoader Factory
public static class Factory implements ModelLoaderFactory<String, Bitmap> {
@Override
public ModelLoader<String,Bitmap> build(Context context,GenericLoaderFactory factories) {
return new PhotoLoader();
}
@Override
public void teardown() {
}
}
}

实现自定义的获取数据格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class PhotoFetcher implements DataFetcher<Bitmap> {
private Bitmap mBitmap;
public PhotoFetcher(String pid) {
mPid = pid;
}
/**
* get image stream ( run in glide background thread)
*/
@Override
public Bitmap loadData(Priority priority) throws Exception {
mBitmap = DSCViewerModel.getThumbnailStream(Integer.parseInt(mPid));// need synchronized
return mBitmap;
}
}

加载Bitmap到ImageView中

使用通用加载方式,这里需要了解Glide中的几个基本概念
参考
参考

  • Model:The type of model representing the resource.
    用来加载数据源,加载图片往往需要如url,资源id,文件,也可以是一条Feed流,Glide把这些抽象为一个Model。Model并不能直接解析为图片,比如一个url,是要转换为网络流的InputStream才能被解析为图片的,Model需要进行一次转换才能做为数据解析的数据源,这些转换后的东西就叫做Data。
  • Data:The data type that the resource {@link com.bumptech.glide.load.model.ModelLoader} will provide that can be decoded by the {@link com.bumptech.glide.load.ResourceDecoder}.
    代表原始的,未修改过的资源,与Data相关的如DataFetcher
  • Resource:The type of the resource that will be loaded.
    修改过的资源,是一个包装类,一个wrapper,它wrap一个对象,使这个对象可以通过对象池进行缓存与重用。
  • Transcode:The type of resource the decoded resource will be transcoded to.
    资源转换器
  • Encoder:用来持久化数据,把数据缓存到磁盘
  • Decoder:用来将数据(InputStream等)解析为Resource

使用GenericRequestBuilder来加载Bitmap
参考
参考

1
2
3
4
5
6
7
8
9
private final GenericRequestBuilder<String, Bitmap, Bitmap, Bitmap> mGlideBuilder;
mGlideBuilder = Glide.with(mContext)
.using(new PhotoLoader(), Bitmap.class)
.from(String.class).as(Bitmap.class)
.encoder(new BitmapEncoder(Bitmap.CompressFormat.PNG, 100))
.decoder(new BitmapBitmapResourceDecoder(mContext))
.cacheDecoder(new FileToStreamDecoder<Bitmap>(new StreamBitmapDecoder(mContext)))
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.placeholder(R.mipmap.ic_launcher);

一些基于Glide的优秀库

1、glide-transformations
transformation库,拥有裁剪,着色,模糊,滤镜等多种转换效果
2、GlidePalette
Palette库,调色板