Glide V3 升级到 Glide V4 踩坑记录

参考

官方文档

Glide最新版V4使用指南

Glide V4使用指南
深入理解Glide

Glide with区别以及Lifecycle

1. 前言

        最近老大让我升级一下Glide, 在此记录一下 Glide V3 升级到 V4 遇到的问题, 方便以后踩坑的同学.

2. 坑ONE: 

Failed to find GeneratedAppGlideModule. You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler in your application and a @GlideModule annotated AppGlideModule implementation or LibraryGlideModules will be silently ignored

其实 log 中的的错误信息已经表达的很明确了, 只是项目中 glide 是放在 common library 中的, applicatin 也需要引入, 但 application 应该使用 kapt...解决办法如下, 

在 common library 中, 添加引用如下:  

api 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
// java使用
// annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

还需要在 application 中添加

// kotlin使用
kapt 'com.github.bumptech.glide:compiler:4.12.0'

// java使用
// annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

然后问题就解决啦~

3. V4使用

3.1 设置 header

直接上代码

@GlideModule
public class MyGlideModuleV4 extends AppGlideModule {
    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, Registry registry) {
        registry.prepend(String.class, InputStream.class, new HeaderedLoader.Factory());
    }

    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        super.applyOptions(context, builder);
    }

    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }

    private static class HeaderedLoader extends BaseGlideUrlLoader {
        public static final Headers HEADERS = new LazyHeaders.Builder()
                .addHeader("User-Agent", "agent_test")
                .addHeader("Accept", "image/webp, */*")
                .build();

        protected HeaderedLoader(ModelLoader concreteLoader) {
            super(concreteLoader);
        }

        protected HeaderedLoader(ModelLoader concreteLoader, @Nullable ModelCache modelCache) {
            super(concreteLoader, modelCache);
        }

        @Override
        protected String getUrl(Object o, int width, int height, Options options) {
            return (String) o;
        }

        @Override
        public boolean handles(@NonNull Object o) {
            // will call [getUrl][getHeaders] if return true
            return true;
        }

        @Nullable
        @Override
        protected Headers getHeaders(Object o, int width, int height, Options options) {
            return HEADERS;
        }

        static class Factory implements ModelLoaderFactory<String, InputStream> {

            @Override
            public ModelLoader<String, InputStream> build(MultiModelLoaderFactory multiFactory) {
                ModelLoader<GlideUrl, InputStream> loader = multiFactory.build(GlideUrl.class, InputStream.class);
                return new HeaderedLoader(loader);
            }

            @Override
            public void teardown() { /* nothing to free */ }
        }
    }
}

需要注意以下3点:

1.V4就不需要读取manifest了, 所以在 isManifestParsingEnabled 返回了 false

2.设置了 header 之后, 需要在 handles 函数中返回 true, 才会生效

3.可优化: 让服务端根据 header 中设置的参数, 返回相应的图片格式. 

比如 app 端同时支持 png 和 webp, 在不影响图片质量的前提下, 就可以返回体积较小的图片, 这样可以节省许多流量. 四舍五入就是省了一个亿~

3.2 其他细节

setDefaultRequestOptions, apply 区别

对 RequestOptions 的设置,Glide V4 还提供了apply 方法设置单次请求的选项,以及setDefaultRequestOptions 设置默认请求选项。

clear 使用

V3中 Glide.clear(imageView) 

V4中 GlideApp.with(context).clear(imageView)

设置宽高

override(width, height) 和 apply(RequestOptions.overrideOf(width, height)区别?

into(width, height) 和 submit(width, height)区别?

// override 和 RequestOptions.overrideOf
GlideApp.with(this)
            .load(R.mipmap.ic_launcher)
            .apply(RequestOptions.overrideOf(500, 500))
            //.override(500, 500)
            .into(findViewById(R.id.iv_req_round))


// into 和 submit
val bitmap = GlideApp.with(this)
            .asBitmap()
            .load(R.mipmap.ic_launcher)
            //.into(500, 500)
            .submit(500, 500)
        thread {
            Logger.i("get bitmap = ${bitmap.get().width}")
        }        

结论

1.override 和 apply(RequestOptions.overrideOf 最终会调用到同一处, 无区别. 只是我这边测试到只有在 ImageView 设置 wrap_content 时, 输入的宽高才会生效

2.into 就是调用的 submit, 不过 into 已经废弃了, 现在推荐使用 submit

为什么使用GlideApp代替Glide

Generated API 模式的设计出于以下两个目的:

1.集成库可以为 Generated API 扩展自定义选项
2.在 Application 模块中可将常用的选项组打包成一个选项在 Generated API 中使用
虽然以上所说的工作均可以通过手动创建 RequestOptions 子类的方式来完成, 但想将它用好更具有挑战, 并且降低了 API 使用的流畅性.

Glide.with activity context fragment 区别

略复杂, 不会整了, 直接看这里

总结

        在升级的过程中, 主要第一个问题卡了半天. 项目使用了kotlin, 应该使用kapt(不能使用 annotationProcessor). 遇到问题时, 还是先看 官方文档 最靠谱.

        如果文章中有错误的地方, 请各位大佬指点. 以防误导前来学习的同学~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃饱很舒服

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值