美文网首页
Glide定制化开发(一)实现网络下载拦截开关

Glide定制化开发(一)实现网络下载拦截开关

作者: Felix_lin | 来源:发表于2021-09-09 17:05 被阅读0次

    用于App配置非wifi环境下是否自动加载图片的开关

    我们的需求:拦截网络下载,但是复用glide原有的内存下载等优势

    做法:在glide网络加载的DataFetcher做定制化开发

    1. 定制化MyAppGlideModule

    • registerComponents中替换 ModelLoader<GlideUrl, InputStream> ,替换我们自定义的okhtttp加载model
    • 定义我们标记的Option,作为开关参数
    @GlideModule
    class MyAppGlideModule : AppGlideModule() {
        companion object{
            /**
             * 是否使用 4g网络不主动加载图片的控制功能
             */
            val OPTION_NETWORK_LOAD_SWITH = Option.memory("option_network_load_swith", false)
            /**
             * 判断是否能从网络加载图片
             * @return Boolean
             */
            fun getLoadFromNetworkEnable():Boolean{
                return BaseData.isAllowCellularDownload||NetworkUtil.isWifi(appContext)
            }
    
        }
    
        override fun applyOptions(context: Context, builder: GlideBuilder) {
            super.applyOptions(context, builder)
        }
    
        override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
            registry.replace(GlideUrl::class.java, InputStream::class.java,  MyOkHttpUrlLoader.Factory())
        }
    }
    

    2. 修改OkHttpUrlLoader为我们自定义的Loader

    • 这一步可以直接从glideOkHttp里面查找复制出来OkHttpUrlLoader,在MyOkHttpUrlLoader里面修改buildLoadData里面替换我们自定义的MyOkHttpStreamFetcher

    • 这里主要操作是从Options中查找我们自定义的开关值,并透传给MyOkHttpStreamFetcher构造函数

    @Override
    public LoadData<InputStream> buildLoadData(
        @NonNull GlideUrl model, int width, int height, @NonNull Options options) {
      boolean optionNetworkLoadSwith= options.get(MyAppGlideModule.Companion.getOPTION_NETWORK_LOAD_SWITH());
      return new LoadData<>(model, new MyOkHttpStreamFetcher(client, model,optionNetworkLoadSwith));
    }
    

    3. 自定义MyOkHttpStreamFetcher

    • 直接从glideOkHttp里面查找复制出来MyOkHttpStreamFetcher

    • 重写loadData方法,如果不满足我们的下载条件直接onFailure回调失败结果

    // Public API.
    @SuppressWarnings("WeakerAccess")
    public MyOkHttpStreamFetcher(Call.Factory client, GlideUrl url, boolean optionNetworkLoadSwith) {
        this.client = client;
        this.url = url;
        this.mOptionNetworkLoadSwith = optionNetworkLoadSwith;
        IMLog.dTag("Felix","--------mOptionNetworkLoadSwith: "+mOptionNetworkLoadSwith);
    }
    
    @Override
    public void loadData(
            @NonNull Priority priority, @NonNull final DataCallback<? super InputStream> callback) {
        this.callback = callback;
        if (!MyAppGlideModule.Companion.getLoadFromNetworkEnable() && mOptionNetworkLoadSwith) {
            onFailure(call, new IOException("[Felix]: Load Failed by Setting-Refused (sLoadImageNotWifiEnable)!!"));
        } else {
            Request.Builder requestBuilder = new Request.Builder().url(url.toStringUrl());
            for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {
                String key = headerEntry.getKey();
                requestBuilder.addHeader(key, headerEntry.getValue());
            }
            Request request = requestBuilder.build();
            call = client.newCall(request);
            call.enqueue(this);
        }
    
    }
    

    完成以上三步即可实现控制开关

    4. 开关使用方法,在glide调用的时候通过在RequestOptions中设置我们定义的options开关即可在需要的地方使用网络下载拦截

    val requestOptions = RequestOptions()
                    .skipMemoryCache(isSkipMemoryCache) //是否允许内存缓存
                    .diskCacheStrategy(DiskCacheStrategy.ALL) //禁止磁盘缓存
    requestOptions.options.set(MyAppGlideModule.OPTION_NETWORK_LOAD_SWITH,true)
    Glide.with(context).load(url).transition(DrawableTransitionOptions.withCrossFade()).apply(requestOptions).into(view)
    

    相关文章

      网友评论

          本文标题:Glide定制化开发(一)实现网络下载拦截开关

          本文链接:https://www.haomeiwen.com/subject/gyxwwltx.html