一、背景知识介绍
Android软件中可能需要加载图片按照来源可以分为3种:
- 资源文件中的图片
- 手机中的图片
- 网络中的图片
加载图片的步骤可以分为3步:找到图片地址、将图片转换为可被加载的对象、通过图片加载控件展示图片。
如果使用Android原生的方法,加载一个网络图片的大致过程为:网络请求图片、读取返回的输入流、将返回的输入流转为Bitmap、切到UI线程将Bitmap显示在控件上。当请求的图片过大时,直接将返回的输入流转为Bitmap可能造成OOM,需要对这种情况进行更复杂的处理。
在这样的需求背景下,出现了许多图片加载框架,而Glide是Google推荐的图片加载框架。
二、使用方法
添加依赖如下,第一个为Glide库,第二个为Generated API的库:
dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
}
主要使用的方法如下:
- .with() 创建图片加载实例
- .load() 指定加载的图片资源
- .into() 指定图片的加载控件
//TODO Glide常用方法补充。
代码示例:
private void glideLoadImage(Context context, ImageView imageView, String imageUrl) {
Glide.with(context) //传入上下文。
.load(imageUrl) //传入图片的URL,load()方法可以传入的参数类型非常多,能想到的都行。
.into(imageView); //指定将图片加载到什么空间。
}
通过使用RequestOptions可以对加载实例进行配置,调用apply()方法为Glide设置自定义配置:
private void glideLoadImage(Context context, ImageView imageView, String imageUrl) {
//配置Glide
RequestOptions options = new RequestOptions()
.placeholder(R.mipmap.loading) //指定加载过程中显示的图片。
.error(R.mipmap.load_error) //指定加载失败时显示的图片。
.circleCrop(); //指定图片为圆角。
Glide.with(context) //传入上下文。
.load(imageUrl) //传入图片的URL,load()方法可以传入的参数类型非常多,能想到的都行。
.into(imageView); //指定将图片加载到什么空间。
}
在开发过程中,可能会使用到各种各样的RequestOptions,如果每次加载时都生成一边配置项,则非常不方便,通常有两种解决方案:
方案一:将各种配置项封装到一个工具类中,通过静态方法来获取。如:
public class ClideOptionsUtils {
public static RequestOptions baseOptions() {
return new RequestOptions()
.placeholder(R.mipmap.loading)
.error(R.mipmap.error);
}
public static RequestOptions circleCropOptions() {
return baseOptions().circleCrop();
}
}
方案二:使用Generated API扩展(重点)。
使用流程:
- 引入Generated API的支持库。
- 创建类,继承AppGlideModule并添加@GlideModule注解。
- 创建类,添加@GlideExtension注解,并实现private构造函数。
代码实例如下:
1、引入Generated API的支持库。即:
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
2、创建类,继承AppGlideModule并添加@GlideModule注解。
/**
* 生成GlideApp对象
*/
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
}
3、 创建类,添加@GlideExtension注解,并实现private构造函数。在这个类中可以定义由注解@GlideOption修饰的static方法,方法的参数及返回值类型都是BaseRequestOptions<?>,这些方法用于封装不同的配置参数。
@GlideExtension
public class MyGlideExtension {
private MyGlideExtension() {}
@GlideOption
public static BaseRequestOptions<?> testOptionsA(BaseRequestOptions<?> options) {
return options.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_search)
.circleCrop();
}
@GlideOption
public static BaseRequestOptions<?> testOptionsB(BaseRequestOptions<?> options) {
return options.placeholder(R.mipmap.ic_launcher)
.optionalCenterInside()
.error(R.mipmap.ic_search);
}
}
4、使用GlideApp.with()而不是Glide.with()来创建加载实例,调用上一步中封装配置参数的方法来应用相应的参数。注意这里调用配置参数的方法时不需要传入参数,Glide在反射调用我们定义的方法时会自动为我们传入参数。GlideApp和上一步中定义的@GlideOption修饰的方法编译器也可能无法找到,同步并Rebuild工程即可。
private void glideAppLoadUrlImage() {
GlideApp.with(GlideTestActivity.this)
.load(R.mipmap.ic_kill)
.testOptionsB() //注意这里不用加参数,Glide会在反射时自动为我们添加参数。
.into(imageView);
}
三、开发中遇到的坑记录
1、Android9.0以上访问网络中http的资源(不是https)时,可能访问不了,需要Manifest文件中对网络安全性校验进行配置。