Glide目前项目中使用到的是两个版本,一个是3.x,另外一个是4.x的。两个版本有一定的差异
Glide 3.x
首先添加依赖
implementation 'com.github.bumptech.glide:glide:3.7.0'
添加网络请求权限
<uses-permission android:name="android.permission.INTERNET" />
代码实现起来比较简单,这里只贴出来逻辑代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.btn);
img = findViewById(R.id.img);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Glide
.with(MainActivity.this)
.load(gifUrl)
.placeholder(R.mipmap.ic_launcher)
.diskCacheStrategy(DiskCacheStrategy.NONE) //设置不要执行硬盘缓存
.error(R.mipmap.ic_launcher_round)
.into(img);
}
});
}
从代码中我们发现,其实核心代码只有一行:
Glide.with(this).load(url).into(imageView);
这一行代码虽然少,但是使用的内容却很多,包括了网络请求,图片加载,图片缓存,图片载入等功能。
首先,调用Glide.with()方法用于创建一个加载图片的实例。with()方法可以接收Context、Activity或者Fragment类型的参数。也就是说我们选择的范围非常广,不管是在Activity还是Fragment中调用with()方法,都可以直接传this。那如果调用的地方既不在Activity中也不在Fragment中呢?也没关系,我们可以获取当前应用程序的ApplicationContext,传入到with()方法当中。注意with()方法中传入的实例会决定Glide加载图片的生命周期,如果传入的是Activity或者Fragment的实例,那么当这个Activity或Fragment被销毁的时候,图片加载也会停止。如果传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会停止。
接下来看一下load()方法,这个方法用于指定待加载的图片资源。Glide支持加载各种各样的图片资源,包括网络图片、本地图片、应用资源、二进制流、Uri对象等等。因此load()方法也有很多个方法重载,除了我们刚才使用的加载一个字符串网址之外,你还可以这样使用load()方法:
private void loadLocalImage(String fileName) {
File file = new File(getExternalCacheDir() + fileName);
Glide.with(this).load(imgUrl).into(img);
}
private void loadAssetImage() {
int resource = R.mipmap.ic_launcher;
Glide.with(this).load(resource).into(img);
}
private void loadBytesImage() {
byte[] image = new byte[1024];
Glide.with(this).load(imgUrl).into(img);
}
private void loadUriImage() {
Uri imageUri = null;
Glide.with(this).load(imageUri).into(img);
}
最后看一下into()方法,这个方法就很简单了,我们希望让图片显示在哪个ImageView上,把这个ImageView的实例传进去就可以了。当然,into()方法不仅仅是只能接收ImageView类型的参数,还支持很多高级技巧,慢慢来。
这里还有其他几个小功能,占位图,错误图和本地硬盘缓存机制。分别代表的是placeholder
,error
和diskCacheStrategy
。
这里我们不仅可以由以上的几个情况,还可以指定当前加载图片的格式,如我们请求到的图片是一个gif图,我们可以强制将他设置为普通图片,通过asBitmap()
方法去实现。这里gif图片不会动态播放,而是定格在第一帧的位置。这里需要注意一下,asBitmap()
方法只能放在特定的位置,有时候我们放置的位置不对,会有报错。
Glide
.with(MainActivity.this)
.load(gifUrl)
.asBitmap()
.placeholder(R.mipmap.ic_launcher)
.diskCacheStrategy(DiskCacheStrategy.NONE) //设置不要执行硬盘缓存
.error(R.mipmap.ic_launcher_round)
.into(img);
设置加载图片的大小
在实际开发中,我们经常遇到服务器返回的图片尺寸较大,和我们想要展示的imageview大小不相符的情况,对于这样的情况,我们可以通过Glide有效的避免OOM的发生。我们可以通过override
方法实现,里面传递需要设置的宽高等数据。
Glide加载图片显示加载百分比
这个网上有很多解答,不过一直没有找到理想的,不过经过自己的摸索和试验,终于自己搞到了一套加载图片显示加载百分比的方法,这个方法还是比较简单的
- 首先需要添加gradle的依赖
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.0.0'
- 新建一个类 ,命名为MyGlideModule,然后让他继承AppGlideModule,然后在当前这个类中,我们需要重写一些方法使Glide得获取图片的网络请求方式发生改变
具体的使用方式是:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
// 添加拦截器到Okhttp
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new ProgressInterceptor());
OkHttpClient okHttpClient = builder.build();
// 更换底层使用Okhttp
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient));
}
@Override
public boolean isManifestParsingEnabled() {
return false;
}
}
其中ProgressInterceptor是一个拦截器,需要我们自己去重写这个类,后面会说到。
除了这一点之外,我们还要注意,在这里我们用到注解@GlideModule。当完成这些之后,需要立刻运行build中的make project方法,就可以生成GlideApp类