图片加载框架Glide使用详解
2017-03-26 19:56
369 查看
最终我还是决定使用Glide,作为我以后的主要图片加载框架。主要基于三点考虑
代码有人维护,不至于出现问题,项目组都搞不定的时候问题无法解决。(ImageLoader已没人维护了)
代码简洁,可读性很好。(Fresco是一个非常优秀的库,但是配置稍显麻烦,同时代码风格读起来有些生疏)
功能强大(400多k的包,包含很多功能,例如:像加载Gif图片就是Picasso做不到的)
但是,首要解决的就是,在Blog中提到的,图片常常加载失败。
![](http://img.blog.csdn.net/20160706141835536)
我们看到仅仅是显示一张错误的图片,但是为什么会这样,日志里面没有任何输出。
监听器配置
2
3
4
5
6
1
2
3
4
5
6
打印日志
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
这里的
这里
如此修改后,看到日志终于打印出来了。查看日志,发现Glide本身自带的网络栈,在网络环境比较差的情况下(只是差,使用其他框架图片可以比较慢的显示出来)
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
看到是
只需两步
Step1:
导入需要替换的HttpClient,可以选择Volley也可以选择OkHttp,我们使用Okhttp,在Module的
2
3
4
1
2
3
4
or
2
1
2
这个版本具体选择多少,可以在https://github.com/bumptech/glide/wiki/Integration-Libraries这里查询到
Step2:
在AndroidMainfest.xml文件中写入
2
3
1
2
3
你可能会有和我一样的疑问,Glide可以通过在配置清单里面配置
能不能写几个meta-data标签,一个标签里面配置一点参数
经过测试,发现这样做也是可以的。但是如果是同一种配置信息,比如你集成了OkHttp,又写一个标签集成Volley,最后一个会把前面的覆盖掉。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
1
2
3
你们发现没有,一般的图片加载框架设置了磁盘缓存和内存缓存就行了,但是Glide还设置了一个图片缓存
2
3
4
5
1
2
3
4
5
最开始我在想,这不多此一举吗,内存缓存大小不就是图片缓存大小么。后面发现不是
1
这里Glide不仅可以缓存图片,还可以缓存其他文件譬如视频之类,也就是说可以把他作为我们的缓存工具来使用,当然缓存方式还是使用LRU。这样我们就不必再去重新集成LruCache和DiskLruCache,再去申请空间,配置。直接可以复用Glide的。
1
使用Android系统提供,从左到右滑出加载动画
1
自定义从小到大填充动画
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
不是说Glide可以根据,控件的大小自动测绘然后填充吗?
但是再有些情况下,譬如App的闪屏页面,还来不及测绘,就需要获取图片数据了。
而且,有些事后,我们可以使用Glide为工具,用这种方式对图片进行压缩裁剪。
可以使用
2
3
4
5
1
2
3
4
5
同理下载图片原理是一样
2
3
4
5
6
7
1
2
3
4
5
6
7
2
3
4
1
2
3
4
优先级设置一览
2
3
4
5
6
1
2
3
4
5
6
代码下载地址:https://github.com/zhouruikevin/ImageLoadPK
顶
1
踩
代码有人维护,不至于出现问题,项目组都搞不定的时候问题无法解决。(ImageLoader已没人维护了)
代码简洁,可读性很好。(Fresco是一个非常优秀的库,但是配置稍显麻烦,同时代码风格读起来有些生疏)
功能强大(400多k的包,包含很多功能,例如:像加载Gif图片就是Picasso做不到的)
但是,首要解决的就是,在Blog中提到的,图片常常加载失败。
打印错误日志与调试
我们看到仅仅是显示一张错误的图片,但是为什么会这样,日志里面没有任何输出。
监听器配置
Glide.with(getContext()) .load(url) .listener(mRequestListener)//配置监听器 .placeholder(Drawables.sPlaceholderDrawable) .error(Drawables.sErrorDrawable) .into(mImageView);1
2
3
4
5
6
1
2
3
4
5
6
打印日志
private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() { @Override public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) { //显示错误信息 Log.w(TAG, "onException: ", e); //打印请求URL Log.d(TAG, "onException: " + model); //打印请求是否还在进行 Log.d(TAG, "onException: " + target.getRequest().isRunning()); return false; } @Override public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { return false; } };1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
这里的
onException捕获异常,如果返回
true表示我们自己处理掉了异常,
false表示交给Glide去处理,因为我们定义了
.error()那么就显示error里面的内容。
这里
onResourceReady表示是否准备资源显示,返回
true表示用户自己已经设置好资源,包括截取操作,动画操作之类的,准备好显示。
false表示交给Glide
如此修改后,看到日志终于打印出来了。查看日志,发现Glide本身自带的网络栈,在网络环境比较差的情况下(只是差,使用其他框架图片可以比较慢的显示出来)
/com.example.imageloadpk W/GlideHolder: onException: java.lang.RuntimeException: java.net.SocketTimeoutException at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:162) ... at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118) Caused by: java.net.SocketTimeoutException at java.net.PlainSocketImpl.read(PlainSocketImpl.java:484) at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37) ...1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
看到是
SocketTimeoutException错误,连接超时。但是发现Picasso没有这个错误,Picasso使用okHttp作为网络栈,好在Glide允许我们自己指定他的网络栈,马上动手修改。
替换掉自带的HttpClient
只需两步 Step1:
导入需要替换的HttpClient,可以选择Volley也可以选择OkHttp,我们使用Okhttp,在Module的
build.gradle文件中配置
dependencies { compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar' compile 'com.squareup.okhttp3:okhttp:3.3.1' }1
2
3
4
1
2
3
4
or
compile 'com.github.bumptech.glide:volley-integration:1.4.0@aar' compile 'com.mcxiaoke.volley:library:1.0.8'1
2
1
2
这个版本具体选择多少,可以在https://github.com/bumptech/glide/wiki/Integration-Libraries这里查询到
Step2:
在AndroidMainfest.xml文件中写入
<meta-data android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule" android:value="GlideModule"/>1
2
3
1
2
3
你可能会有和我一样的疑问,Glide可以通过在配置清单里面配置
能不能写几个meta-data标签,一个标签里面配置一点参数
经过测试,发现这样做也是可以的。但是如果是同一种配置信息,比如你集成了OkHttp,又写一个标签集成Volley,最后一个会把前面的覆盖掉。
修改缓存大小、位置、加载图片质量
和指定HttpClent为OkHttp一样,只不过我们需要配置一些信息在applyOptions()函数里面
public class GlideConfigModule implements GlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { // 指定位置在packageName/cache/glide_cache,大小为MAX_CACHE_DISK_SIZE的磁盘缓存 builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", ConfigConstants.MAX_CACHE_DISK_SIZE)); //指定内存缓存大小 builder.setMemoryCache(new LruResourceCache(ConfigConstants.MAX_CACHE_MEMORY_SIZE)); //全部的内存缓存用来作为图片缓存 builder.setBitmapPool(new LruBitmapPool(ConfigConstants.MAX_CACHE_MEMORY_SIZE)); builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);//和Picasso配置一样 } @Override public void registerComponents(Context context, Glide glide) { } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<meta-data android:name="com.example.imageloadpk.adapter.config.GlideConfigModule" android:value="GlideModule"/>1
2
3
1
2
3
Glide缓存方式,可以作为其他用途
你们发现没有,一般的图片加载框架设置了磁盘缓存和内存缓存就行了,但是Glide还设置了一个图片缓存builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", ConfigConstants.MAX_CACHE_DISK_SIZE)); //指定内存缓存大小 builder.setMemoryCache(new LruResourceCache(ConfigConstants.MAX_CACHE_MEMORY_SIZE)); //全部的内存缓存用来作为图片缓存 builder.setBitmapPool(new LruBitmapPool(ConfigConstants.MAX_CACHE_MEMORY_SIZE));1
2
3
4
5
1
2
3
4
5
最开始我在想,这不多此一举吗,内存缓存大小不就是图片缓存大小么。后面发现不是
图片缓存 <= 内存缓存1
1
这里Glide不仅可以缓存图片,还可以缓存其他文件譬如视频之类,也就是说可以把他作为我们的缓存工具来使用,当然缓存方式还是使用LRU。这样我们就不必再去重新集成LruCache和DiskLruCache,再去申请空间,配置。直接可以复用Glide的。
使用加载动画
Glide提供淡如淡出.crossFade()1
1
使用Android系统提供,从左到右滑出加载动画
.animate(android.R.anim.slide_in_left)1
1
自定义从小到大填充动画
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <scale android:duration="@android:integer/config_longAnimTime" android:fromXScale="0.1" android:fromYScale="0.1" android:pivotX="50%" android:pivotY="50%" android:toXScale="1" android:toYScale="1"/> </set>1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
.animate(R.anim.scale)1
1
使用缓存也加载动画
但是,动画默认是在图片没有缓存的情况下才加载,想想也是合理的,如果图片已近下载到本地加载速度将会非常快,这个时候使用动画过渡反而碍事。要让从缓存中图片呈现也加载动画不能通过这种方式实现,可以用监听器来做。private RequestListener<String, GlideBitmapDrawable> mAnimationRequestListener = new RequestListener<String, GlideBitmapDrawable>() { @Override public boolean onException(Exception e, String model, Target<GlideBitmapDrawable> target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(GlideBitmapDrawable resource, String model, Target<GlideBitmapDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { dissProgress(); if (isFromMemoryCache) { //如果是从缓存加载,设置动画效果 mIvShow.setAnimation(AnimationUtils.loadAnimation(mContext, R.anim.scale)); } //返回true表示拦截不再传递,false表示事件会传递下去 return false; } };1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
指定大小
.override(600, 300)1
1
不是说Glide可以根据,控件的大小自动测绘然后填充吗?
但是再有些情况下,譬如App的闪屏页面,还来不及测绘,就需要获取图片数据了。
而且,有些事后,我们可以使用Glide为工具,用这种方式对图片进行压缩裁剪。
不为ImageView类型加载
譬如加载的控件类型不是ImageView,是个自定义的布局。或者加载为Background的形式。可以使用
SimpleTarget类型,这里指定他的大小为500*100,加载为背景图片。
.into(new SimpleTarget<Drawable>(500, 100) { @Override public void onResourceReady(Drawable resource, GlideAnimation<? super Drawable> glideAnimation) { mBtnClear.setBackground(resource); }1
2
3
4
5
1
2
3
4
5
同理下载图片原理是一样
.into(new SimpleTarget<Bitmap>() { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { //toSave Log.d(TAG, "onResourceReady: save successful"); } });1
2
3
4
5
6
7
1
2
3
4
5
6
7
请求优先级调整
Glide.with(mContext) .load(Url.IMAGE_URL_TROCHILIDAE) .priority(Priority.HIGH) .into(mIvTonyRight);1
2
3
4
1
2
3
4
优先级设置一览
public enum Priority { IMMEDIATE, HIGH, NORMAL, LOW, priority, }1
2
3
4
5
6
1
2
3
4
5
6
代码下载地址:https://github.com/zhouruikevin/ImageLoadPK
顶
1
踩
相关文章推荐
- Android图片加载Glide框架使用详解
- Android图片加载Glide框架使用详解
- 图片加载框架Glide使用详解
- Android图片加载框架之Glide使用详解
- Android图片加载Glide框架使用详解
- Android图片加载Glide框架使用详解
- 关于Glide图片加载框架的使用详解
- Android 图片加载框架Glide使用详解
- 图片加载框架Glide使用详解
- Android图片加载Glide框架使用详解
- 图片加载框架Glide的简单使用
- Android 平滑图片加载和缓存库 Glide 使用详解
- 【框架】Android图片加载Glide使用方法
- Android图片加载框架Glide使用总结
- 图片加载框架Glide使用教程--
- Android studio 图片加载框架Glide介绍及使用
- Glide图片加载框架的简单使用
- 使用glide图片加载框架将网络图片展示并在listview中
- Android图片加载框架Glide使用总结
- Android Glide Google 推荐加载图片框架(加载图片详解篇)