图片加载框架Glide使用详解
2016-07-16 03:20
686 查看
最终我还是决定使用Glide,作为我以后的主要图片加载框架。主要基于三点考虑
代码有人维护,不至于出现问题,项目组都搞不定的时候问题无法解决。(ImageLoader已没人维护了)
代码简洁,可读性很好。(Fresco是一个非常优秀的库,但是配置稍显麻烦,同时代码风格读起来有些生疏)
功能强大(400多k的包,包含很多功能,例如:像加载Gif图片就是Picasso做不到的)
但是,首要解决的就是,在Blog中提到的,图片常常加载失败。
我们看到仅仅是显示一张错误的图片,但是为什么会这样,日志里面没有任何输出。
监听器配置
打印日志
这里的
这里
如此修改后,看到日志终于打印出来了。查看日志,发现Glide本身自带的网络栈,在网络环境比较差的情况下(只是差,使用其他框架图片可以比较慢的显示出来)
看到是
Step1:
导入需要替换的HttpClient,可以选择Volley也可以选择OkHttp,我们使用Okhttp,在Module的
or
这个版本具体选择多少,可以在https://github.com/bumptech/glide/wiki/Integration-Libraries这里查询到
Step2:
在AndroidMainfest.xml文件中写入
你可能会有和我一样的疑问,Glide可以通过在配置清单里面配置
能不能写几个meta-data标签,一个标签里面配置一点参数
经过测试,发现这样做也是可以的。但是如果是同一种配置信息,比如你集成了OkHttp,又写一个标签集成Volley,最后一个会把前面的覆盖掉。
最开始我在想,这不多此一举吗,内存缓存大小不就是图片缓存大小么。后面发现不是
这里Glide不仅可以缓存图片,还可以缓存其他文件譬如视频之类,也就是说可以把他作为我们的缓存工具来使用,当然缓存方式还是使用LRU。这样我们就不必再去重新集成LruCache和DiskLruCache,再去申请空间,配置。直接可以复用Glide的。
使用Android系统提供,从左到右滑出加载动画
自定义从小到大填充动画
不是说Glide可以根据,控件的大小自动测绘然后填充吗?
但是再有些情况下,譬如App的闪屏页面,还来不及测绘,就需要获取图片数据了。
而且,有些事后,我们可以使用Glide为工具,用这种方式对图片进行压缩裁剪。
可以使用
同理下载图片原理是一样
优先级设置一览
代码下载地址:https://github.com/zhouruikevin/ImageLoadPK
代码有人维护,不至于出现问题,项目组都搞不定的时候问题无法解决。(ImageLoader已没人维护了)
代码简洁,可读性很好。(Fresco是一个非常优秀的库,但是配置稍显麻烦,同时代码风格读起来有些生疏)
功能强大(400多k的包,包含很多功能,例如:像加载Gif图片就是Picasso做不到的)
但是,首要解决的就是,在Blog中提到的,图片常常加载失败。
打印错误日志与调试
我们看到仅仅是显示一张错误的图片,但是为什么会这样,日志里面没有任何输出。
监听器配置
Glide.with(getContext()) .load(url) .listener(mRequestListener)//配置监听器 .placeholder(Drawables.sPlaceholderDrawable) .error(Drawables.sErrorDrawable) .into(mImageView);
打印日志
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; } };
这里的
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) ...
看到是
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' }
or
compile 'com.github.bumptech.glide:volley-integration:1.4.0@aar' compile 'com.mcxiaoke.volley:library:1.0.8'
这个版本具体选择多少,可以在https://github.com/bumptech/glide/wiki/Integration-Libraries这里查询到
Step2:
在AndroidMainfest.xml文件中写入
<meta-data android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule" android:value="GlideModule"/>
你可能会有和我一样的疑问,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) { } }
<meta-data android:name="com.example.imageloadpk.adapter.config.GlideConfigModule" android:value="GlideModule"/>
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));
最开始我在想,这不多此一举吗,内存缓存大小不就是图片缓存大小么。后面发现不是
图片缓存 <= 内存缓存
这里Glide不仅可以缓存图片,还可以缓存其他文件譬如视频之类,也就是说可以把他作为我们的缓存工具来使用,当然缓存方式还是使用LRU。这样我们就不必再去重新集成LruCache和DiskLruCache,再去申请空间,配置。直接可以复用Glide的。
使用加载动画
Glide提供淡如淡出.crossFade()
使用Android系统提供,从左到右滑出加载动画
.animate(android.R.anim.slide_in_left)
自定义从小到大填充动画
<?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>
.animate(R.anim.scale)
使用缓存也加载动画
但是,动画默认是在图片没有缓存的情况下才加载,想想也是合理的,如果图片已近下载到本地加载速度将会非常快,这个时候使用动画过渡反而碍事。要让从缓存中图片呈现也加载动画不能通过这种方式实现,可以用监听器来做。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; } };
指定大小
.override(600, 300)
不是说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); }
同理下载图片原理是一样
.into(new SimpleTarget<Bitmap>() { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { //toSave Log.d(TAG, "onResourceReady: save successful"); } });
请求优先级调整
Glide.with(mContext) .load(Url.IMAGE_URL_TROCHILIDAE) .priority(Priority.HIGH) .into(mIvTonyRight);
优先级设置一览
public enum Priority { IMMEDIATE, HIGH, NORMAL, LOW, priority, }
代码下载地址:https://github.com/zhouruikevin/ImageLoadPK
相关文章推荐
- 按右键另存图片只能存BMP
- photoshop去除图片上的水印
- upload上传单张图片
- 图片引发的溢出危机(图)
- C# WinForm控件对透明图片重叠时出现图片不透明的简单解决方法
- C#实现把彩色图片灰度化代码分享
- C#将图片和字节流互相转换并显示到页面上
- C#监控文件夹并自动给图片文件打水印的方法
- 纯CSS实现的当鼠标移上图片添加阴影效果代码
- 如何使用C#从word文档中提取图片
- C#实现打开画图的同时载入图片、最大化显示画图窗体的方法
- C#图片添加水印的实现代码
- 随鼠标移动的图片或文字特效代码
- CSS 图片横向排列实现代码
- C#实现将Email地址转成图片显示的方法
- C#实现图片加相框的方法
- 超级经典一套鼠标控制左右滚动图片带自动翻滚
- 用css实现图片垂直居中的使用技巧
- 一起动手编写Android图片加载框架
- C++实现读取图片长度和宽度