Android 图片加载框架Glide
一:概述
Glide是目前在Android的开发中十分的受欢迎,简直是轻易开一个我的项目都会想到应用Glide当图片加载框架
1.次要特点:
(1)反对Memory和Disk图片缓存
(2)反对gif和webp格局图片
(3)依据Activity/Fragment生命周期主动治理申请
(4)应用Bitmap Pool能够应用Bitmap复用
(5)对于回收的Bitmap会被动调用recycle,缩小零碎回收压力
2.依赖
高版本
//这是对于Glide 4的依赖和之前Glide 有一些区别 implementation 'com.github.bumptech.glide:glide:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' //相比于Glide 3,这里要多增加一个compiler的库,这个库是用于生成Generated API的
对于Kolin
如果你在 Kotlin 编写的类里应用 Glide 注解,你须要引入一个 kapt 依赖,以代替惯例的 annotationProcessor 依赖
dependencies { implementation 'com.github.bumptech.glide:glide:4.11.0' kapt 'com.github.bumptech.glide:compiler:4.11.0'}
低版本
implementation 'com.github.bumptech.glide:glide:3.7.0'
咱们针对于Glide 3的一些办法应用解说
二:根本应用
在AndroidManifest文件增加权限
<uses-permission android:name="android.permission.INTERNET"/>
public class ElevenActivity extends AppCompatActivity implements View.OnClickListener { private Button btn; private ImageView imageView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_eleven); imageView= findViewById(R.id.iv_img); btn=findViewById(R.id.btn_click); btn.setOnClickListener(this::onClick); } @Override public void onClick(View v) { String url = "http://guolin.tech/book.png"; Glide.with(this).load(url).into(imageView);//Glide申请加载图片的最简略 }}
1.加载图片
Glide.with(this).load(url).into(imageView);
加载网络图片,从文件中加载,加载资源id等
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Test.jpg");Glide.with(context).load(file).into(imageViewFile);
2.占位符placeholder加载时候未加载进去前先有一个占位图,error加载失败图片,fallback 在Drawable 在申请的url/model为 null 时展现。
Glide.with(this).load(url).centerCrop().placeholder(R.mipmap.ic_launcher).error(R.mipmap.login_icon).into(imageView);//占位符 Glide.with(this).load(url).fallback(R.mipmap.ic_launcher).into(imageView);// 如果申请的url/model为 null 的时候展现的图片 (如果没有设置,还是展现placeholder的占位符)
3.asGif(),asBitmap()显示gif动画,asGif()判断是否是gif动画,asBitmap()能够加载动态gif图即gif图的第一帧
Glide.with(this).load(url).asGif().into(imageView);//显示Gif动画 Glide.with(this).load(url).asBitmap().into(imageView);//显示Bitmap图片
4.设置动画
.crossFade() :Glide提供淡如淡出;
crossFade(int duration)//设置动画工夫
crossFade(Animation animation, int duration)//自定义动画和工夫
.dontAnimate()//勾销动画
.animate(android.R.anim.slide_in_left):Android零碎提供,从左到右滑出加载动画
Glide.with(this).load(url).crossFade().into(imageView); Glide.with(this).load(url).animate(android.R.anim.slide_in_left).into(imageView);//从左到右加载图片
5.调整图片大小
单位是像素,裁剪你的图片大小。其实Glide曾经会主动依据你ImageView裁剪照片来放在缓存中了。然而不想适应ImageView大小的时候,能够调用这个办法.override()为ImageView指定大小
Glide.with(this).load(url).override(100,100).animate(android.R.anim.slide_in_left).into(imageView);
6.裁剪图片.fitCenter()和.CenterCrop()
当须要裁剪大小时,有个.centerCrop办法,这个办法的裁剪会让你的ImageView四周不会留白,还有一个.fitCenter()办法,示意让你的Image齐全显示,尺寸不对时,四周会留白。
Glide.with(this).load(url).fitCenter().animate(android.R.anim.slide_in_left).into(imageView);
7.设置缩略图.thumbnail()
.thumbnail()办法的目标就是让用户先看到一个低解析度的图,点开后,再加载一个高解析度的图。
Glide.with(this).load(url).fitCenter().thumbnail(0.1f).animate(android.R.anim.slide_in_left).into(imageView);
一种更高级的缩略图加载形式:
当缩略图也须要通过网络加载全副解析度的时候。
private void loadImageThumbnailRequest() { DrawableRequestBuilder<String> thumbnailRequest = Glide.with(context.load(eatFoodyImages[2]); Glide.with(context).load(UsageExampleGifAndVideos.gifUrl).thumbnail(thumbnailRequest).into(imageView);}
8.设置图片显示成果(圆角、圆形、高斯含糊、蒙板、裁剪等等).bitmapTransform()
Glide.with(this).load(R.mipmap.ic_image_sample) //含糊 .bitmapTransform(new BlurTransformation(this)) //圆角 .bitmapTransform(new RoundedCornersTransformation(this, 24, 0, RoundedCornersTransformation.CornerType.ALL)) //遮蔽 .bitmapTransform(new MaskTransformation(this, R.mipmap.ic_launcher)) //灰度 .bitmapTransform(new GrayscaleTransformation(this)) //圆形 .bitmapTransform(new CropCircleTransformation(this)) .into(imageView);
除此之外还有实现诸如马赛克、明暗度等更多滤镜解决:
- ToonFilterTransformation
- SepiaFilterTransformation
- ContrastFilterTransformation
- InvertFilterTransformation
- PixelationFilterTransformation
- SketchFilterTransformation
- SwirlFilterTransformation
- BrightnessFilterTransformation
- KuwaharaFilterTransformation
- VignetteFilterTransformation
9.Gilde的缓存
缓存是为了缩小或者杜绝多的网络申请。为了防止缓存,Glide用了内存缓存和‘外存缓存机制’,并且 提供了相应的办法,齐全封装,不须要解决细节。Glide会主动缓存到内存,除非调用.skipMemoryCache( true )。只管调用了这个,Glide还是会缓存到外存,还有一种情景,就是有一张图片,然而这张图变动十分快,这个时候可能并不想缓存到外存中,就应用.diskCacheStrategy( DiskCacheStrategy.NONE )。如果你两种都不须要,能够两个办法组合着一起应用。
- DiskCacheStrategy.NONE 什么都不缓存
- DiskCacheStrategy.SOURCE 仅仅只缓存原来的全分辨率的图像
- DiskCacheStrategy.RESULT 仅仅缓存最终的图像,即升高分辨率后的(或者是转换后的)
DiskCacheStrategy.ALL 缓存所有版本的图像(默认行为)
//设置跳过内存缓存 Glide.with(this).load(url).animate(android.R.anim.slide_in_left).skipMemoryCache(true).into(imageView); //设置硬盘缓存没有Glide.with(this).load(url).animate(android.R.anim.slide_in_left).diskCacheStrategy(DiskCacheStrategy.NONE).into(imageView);
10.申请的优先级.priority()
载图片必定也是有先后顺序,Glide提供了.priority()这个办法,它接管以下几个参数:- Priority.LOW
- Priority.NORMAL
- Priority.HIGH
- Priority.IMMEDIATE
Glide.with(this).load(url).animate(android.R.anim.slide_in_left).diskCacheStrategy(DiskCacheStrategy.NONE).priority(Priority.LOW).into(imageView);
11.监听器配置.listener()
@Override public void onClick(View v) { String url = "http://guolin.tech/book.png"; Glide.with(this).load(url).animate(android.R.anim.slide_in_left).listener(mRequestListener).into(imageView); } private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() { @Override public boolean onException(Exception e, String model, com.bumptech.glide.request.target.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, com.bumptech.glide.request.target.Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { return false; } };}
这里的onException捕捉异样,如果返回true示意咱们本人解决掉了异样,false示意交给Glide去解决,因为咱们定义了.error()那么就显示error外面的内容。
这里onResourceReady示意是否筹备资源显示,返回true示意用户本人曾经设置好资源,包含截取操作,动画操作之类的,筹备好显示。false示意交给Glide
如此批改后,就可能看到图片加载日志了,不便咱们调试
12.替换掉自带的HttpClient
导入须要替换的HttpClient,能够抉择Volley也能够抉择OkHttp,咱们应用Okhttp,在Module的build.gradle文件中配置
implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"
13.Glide 4应用
而Glide 4中引入了一个RequestOptions对象,将这一系列的API都挪动到了RequestOptions当中。这样做的益处是能够使咱们解脱简短的Glide加载语句,而且还能进行本人的API封装,因为RequestOptions是能够作为参数传入到办法中的。
RequestOptions options = new RequestOptions() .placeholder(R.drawable.ic_launcher_background) .error(R.drawable.error) .diskCacheStrategy(DiskCacheStrategy.NONE);Glide.with(this) .load(url) .apply(options) .into(imageView);
14.对于图片变换,最初咱们再来看一个十分优良的开源库,glide-transformations。它实现了很多通用的图片变换成果,如裁剪变换、色彩变换、含糊变换等等,使得咱们能够十分轻松地进行各种各样的图片变换
增加库
dependencies { implementation 'jp.wasabeef:glide-transformations:3.0.1'}
三:应用Generated API
Generated API是Glide 4中全新引入的一个性能,它的工作原理是应用注解处理器 (Annotation Processor) 来生成出一个API,在Application模块中可应用该流式API一次性调用到RequestBuilder,RequestOptions和集成库中所有的选项。
Generated API对于相熟Glide 3的敌人来说那是再简略不过了,基本上就是和Glide 3截然不同的用法,只不过须要把Glide关键字替换成GlideApp关键字,如下所示:
GlideApp.with(this) .load(url) .placeholder(R.drawable.loading) .error(R.drawable.error) .skipMemoryCache(true) .diskCacheStrategy(DiskCacheStrategy.NONE) .override(Target.SIZE_ORIGINAL) .circleCrop() .into(imageView);
不过,有可能你的IDE中会提醒找不到GlideApp这个类。这个类是通过编译时注解主动生成的,首先确保你的代码中有一个自定义的模块,并且给它加上了@GlideModule注解,也就是咱们在上一节所讲的内容。而后在Android Studio中点击菜单栏Build -> Rebuild Project,GlideApp这个类就会主动生成了。
@GlideModulepublic final class MyAppGlideModule extends AppGlideModule { @Override public boolean isManifestParsingEnabled() { return false; } @Override public void registerComponents( @NonNull Context context, @NonNull Glide glide, Registry registry) { // 配置glide网络加载框架 registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory()); } @Override public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) { builder.setDefaultRequestOptions( new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888)); if (BuildConfig.DEBUG) { builder.setLogLevel(Log.DEBUG); } }}
能够看到,在MyAppGlideModule类当中,咱们重写了applyOptions()和registerComponents()办法,这两个办法别离就是用来更改Glide配置以及替换Glide组件的。
留神在MyAppGlideModule类在下面,咱们退出了一个@GlideModule的注解,这是Gilde 4和Glide 3最大的一个不同之处。在Glide 3中,咱们定义了自定义模块之后,还必须在AndroidManifest.xml文件中去注册它能力失效,而在Glide 4中是不须要的,因为@GlideModule这个注解曾经可能让Glide辨认到这个自定义模块了
四:自定义本人的扩大类
定制本人的API须要借助@GlideExtension和@GlideOption这两个注解。创立一个咱们自定义的扩大类,代码如下所示:
@GlideExtensionpublic class MyGlideExtension { private MyGlideExtension() { } @GlideOption @NonNull public static BaseRequestOptions<?> roundCorner(@NonNull BaseRequestOptions<?> options) { return options.transform(new RoundedCorners(SizeUtils.dp2px(5))); }}
这里咱们定义了一个MyGlideExtension类,并且给加上了一个@GlideExtension注解,而后要将这个类的构造函数申明成private,这都是必须要求的写法。
接下来就能够开始自定义API了,这里咱们定义了一个cacheSource()办法,示意只缓存原始图片,并给这个办法加上了@GlideOption注解。留神自定义API的办法都必须是静态方法,而且第一个参数必须是RequestOptions,前面你能够退出任意多个你想自定义的参数
GlideApp.with(this) .load(url) .cacheSource() .into(imageView);
五:Glide 4应用增加依赖
implementation 'com.github.bumptech.glide:glide:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"
应用:
Glide.with(this).load(R.mipmap.login_icon).placeholder(R.mipmap.ic_launcher).into(imageView); //或者应用 RequestOptions options=new RequestOptions().placeholder(R.mipmap.ic_launcher);//questOptions 容许你一次指定一系列的选项,而后对多个加载重用它们 Glide.with(this).load(R.mipmap.login_icon).apply(options).into(imageView); //这样抽取进去能够屡次加载
自定义模块@GlideMoudule,这样的话就能创立一个自定模块类
咱们重写了applyOptions()和registerComponents()办法,这两个办法别离就是用来更改Glide配置以及替换Glide组件的。
@GlideModulepublic final class MyAppGlideModule extends AppGlideModule { @Override public boolean isManifestParsingEnabled() { return false; } @Override public void registerComponents( @NonNull Context context, @NonNull Glide glide, Registry registry) { // 配置glide网络加载框架 registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory()); } @Override public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) { builder.setDefaultRequestOptions( new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888)); if (BuildConfig.DEBUG) { builder.setLogLevel(Log.DEBUG); } }}
而后Bulid-->Rebulid Project
//这样的话就是吧Glide 换成GlideApp GlideApp.with(this).load(R.mipmap.login_icon).into(imageView);
自定义Api: mini()办法
@GlideExtensionpublic class MyGlideExtension { private MyGlideExtension() { } @GlideOption @NonNull public static BaseRequestOptions<?> mini( @NonNull BaseRequestOptions<?> options, int size) { return options.fitCenter().override(size); } //这是一个Api扩大,应用居中裁剪和调整图片size大小尺寸}
而后Bulid-->Rebulid Project
最初调用
GlideApp.with(this).load(R.mipmap.login_icon).mini(66).into(imageView);
Glide相干博客:https://guolin.blog.csdn.net/...
END:我开始在人世间漂流, 抉择过大大小小的幻想