Glide下载上传进程监听

作者: 网络编程  发布:2019-09-08

原著地址:

本文由jessyan投稿。

jessyan的博客地址:

发布上篇作品 笔者一行代码都不写完结Toolbar!你却还在封夸口aseActivity? 已是二个月前的事体,当时有些人说自身是标题党,也许有人不承认自己的故事情节,不过那也不并不要紧碍小编,两日夺得丹佛掘金当周周榜第一,并被 鸿洋大伙儿号 转发,累计阅读量当先 5万

1. 前言

=

上篇作品的斟酌成果让 MVPArms 具备了 监听整个 App 全数 Activity 以及 Fragment 的生命周期,并可向其生命周期内插入代码 的法力,此番本身又拿着近期的另一项研讨成果向咱们反映,当然一样也是 MVPArms 上的新扩展效果与利益

上篇作品的切磋成果让 MVPArms 具有了 监听整个 App 全体 Activity 以及 Fragment 的生命周期(饱含三方库),并可向其生命周期内插入代码 的效果,此次笔者又拿着近些日子的另一项切磋成果向大家报告,当然一样也是 MVPArms 上的新扩张效果与利益。

正文提到的MVPArms地址为:

Github : 你的 Star 是本人坚贞不屈的重力 ✊

图片 1

=

2. 罗列须要

=

Github : 你的 Star 是小编坚定不移的重力 ✊

上传下载是绝大非常多 APP 必备的效应,展现进程条也是巩固顾客体验的主要一环,当然作为 可配置化集成框架 MVPArms 的撰稿人,小编想重新升高开垦者的行使体验以及支付功用,那作者就必得提供一套建设方案。

于是乎作者展开 Github 轻松的搜了一圈与 Retrofit , Okhttp , Glide 有关的快慢监听库,库到是贪心不足,但是都尚未高达自己想要的须要,于是自身卷起袖子,希图撸一个,当然,开撸在此之前要先轻巧梳理下团结的要求

  1. 其一库一定要辅助四个阳台,Okhttp , Retrofit , Glide 那八个必得同期扶助

  2. 固然协理那多少个库,然而Curry面并不能够包括那七个库,让顾客本身去引进,减小库的容量

  3. 采纳必需求简明!!!,最棒能一行代码解决

  4. 凌犯性低,并无需改在此以前写好的互连网诉求代码,引进与不引进那个库,对在此以前的代码都不能够有别的影响

  5. 低耦合,客户做网络恳求的代码,相对无法和速度接收端的代码有太多关系

  6. 在 App 的其余地方都能接受到有些互联网乞请的 进度音讯

  7. 岂但要求满意,三个数据源对应二个进程接收端的一对一关联,还供给满足七个数据源对应多少个进程接收端的,一对多涉及,那样就能够一齐更新三个不一样职分的进程条

  8. 暗许运营在主线程,让使用者少去切换线程的沉闷

3 供给剖判及调查切磋

爽一下子,写出了这般多需求,当产品经营就是四个字爽!

留心一看这8个必要,刹那间懵逼了,妹的那不是坑自身吗?除了最终一项,作者精通能够用 Handler 来促成,其余完全没思路啊,得了,作为一个上档次男青少年自己得主动啊,先从第贰个须求初步深入分析吧!

图片 2gif

须要 1 (多平台支撑)

写以前翻了下 谷歌 发现,Okhttp 完成上传下载进程监听,并不困难,只用重写 RequestBody 和 ResponseBody ,并协作 Interceptor 将每一种乞求原有的 RequestBody 和 ResponseBody 替换,就能够兑现,都以模版代码,复制粘贴就足以了。

而 Retrofit 底层使用的是 Okhttp,那就也得以同样实现速度监听

而是 Glide怎么落实速度监听呢? 

自己的率先影响正是既然 Retrofit 使用 Okhttp 须求网络就足以特别轻巧的落到实处,那将 Glide 的平底需要框架换到 Okhttp 也能够完成咯,作为叁个这么牛逼的库,分明有扩大的章程,于是当即去翻 Glide 的源码,印证了协调的主张,开采 Glide 底层是选择的 HttpConenction 去伏乞互连网,而且这些类是能够被调换的,急速 Google 了下。

compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'

ok,找到应用方案,可用上面提供的类,将底层央求框架替换为 Okhttp ,那个框架最大旨的地点已经找达到成格局,主尽管经过 Okhttp 完毕,仿佛吃了定心丸,弹指间舒坦。

-

上传下载是大多数 APP 必备的机能,展现进程条也是抓好客户体验的首要一环,当然作为 可配置化集成框架 MVPArms 的撰稿人,小编想再一次升高开拓者的行使体验以及开垦作用,那我就必得提供一套设计方案

要求 2 (减小体量)

其一须求 Google 了下,也特别简单,用 provided 引进依赖框架,打包时引进的框架就不会含有进去。

于是乎笔者张开 Github 轻巧的搜了一圈与 Retrofit , Okhttp , Glide 有关的速度监听库,库到是比较多,可是都未有完成自我想要的急需,于是作者卷起袖子,策画撸二个,当然,开撸此前要先简单梳理下自个儿的供给

需求 3 (一行代码落成)

对此这种对外 Api 设计上的须要,大家应该把中央职能达成了,再逐步优化到想到达的对象所以先解析下边包车型地铁须要。

  1. 其一库一定要帮衬三个平台,Okhttp , Retrofit , Glide 那多少个必需同有的时候间补助
  2. 固然如此协理这多个库,可是Curry面并无法包罗那多个库,让顾客本人去引进,减小库的体量
  3. 选用必得求轻易!!!,最棒能一行代码消除
  4. 凌犯性低,并无需改在此以前写好的网络央浼代码,引进与不引进那些库,对以前的代码都不能够有任何影响
  5. 低耦合,客户做网络乞求的代码,绝对不可以够和进程接收端的代码有太多涉及
  6. App 的另外岗位都能经受到某些互连网伏乞的 进程音讯
  7. 非但需求知足,三个数据源对应二个进程接收端的一对一事关,还须求满足四个数据源对应八个进程接收端的,一对多关系,那样就足以一同更新多少个例外职位的进度条
  8. 默许运维在主线程,让使用者少去切换线程的愤懑

必要 4 (侵入性低)

因为需求 1 已经涉嫌,达成上传和下载速度监听的主要即是,在 Interceptor 军长每一种央浼原有的 RequestBody 和 ResponseBody 替换来重写后的。

爽!一下子,写出了这般多须求,当产品经营正是三个字爽!

4. 哪些鉴定分别供给监听进程的伸手?

留神一看那8个需求,须臾间懵逼了,妹的那不是坑本人呢?除了最后一项,作者明白能够用 Handler 来完毕,别的完全没思路啊,得了,作为三个优质男青年自己得主动啊,先从第2个要求开端深入分析吧!

写在此之前翻了下 Google 发现,Okhttp 完结上传下载进程监听,并不困难,只用重写 RequestBodyResponseBody ,并配合 Interceptor 将各种央求原有的 RequestBodyResponseBody 替换,就足以兑现,都以模版代码,复制粘贴就能够了,而 Retrofit 底层使用的是 Okhttp,这就也足以一样完结速度监听

轮换是简约,不过不是种种央求都急需监听上传和下载速度,不容许每一个央浼都替换啊,早先自个儿想到的是给需求监听进程的乞请生成个暗记,然后在 Interceptor 中解析到这些标识,就表达那么些恳求需求监听上传或下载进程,然后就起来交替之

于是乎作者想到最简易的议程正是在乞求的时候加四个自定义的 Header ,那样就不用再定义别的的类, Interceptor 遍历所有 Header 开掘有这些自定义 Header ,就能够轮换。

不过这样并从未化解急需 4,因为那样让顾客比平日恳请时多了个操作,若是想让以前的代码具备进度监听成效,将在二个个挨着改,扩展了劳动量,何况这么些操作是对准于自身这些库而爆发的,当客户并不想利用这一个库的时候,会牵涉到修改在此以前的代码,那样还扩充了侵入性。

而是 Glide怎么落实速度监听呢? 小编的首先反应就是既然 Retrofit 使用 Okhttp 诉求网络就足以非常轻松的落到实处,那将 Glide 的底层央浼框架换来 Okhttp 也得以达成咯,作为几个如此牛逼的库,明确有恢宏的点子,于是立时去翻 Glide 的源码,印证了温馨的主张,发掘 Glide 底层是利用的 HttpConenction 去央浼网络,而且那些类是能够被交流的,飞快 Google 了下

Url 作为标识

二个思想一闪而过,还要哪些标识, Url 是举世无双的, 不就足以看成标志吗!!!

compile 'com.github.bumptech.glide:okhttp3-integration:x.y.z@aar'

急需 5 (低耦合) ,要求 6 (任何地方都可接收),以及 须要 7 (一对多)。

ok,找到实施方案,可用上边提供的库,将底层伏乞框架替换为 Okhttp ,那个框架最大旨的地点已经找到落成形式,首即使通过 Okhttp 完结,仿佛吃了定心丸,须臾间舒坦

其一要求 Google 了下,也特别轻便,用 provided 依赖框架,打包时依赖的框架就不会包蕴进去

借用 EventBus 思想

缘何把那一个供给放在一同吗,因为那多个必要让自家想到了 伊芙ntBus ,多个观看者使用同一个标识将本人注册进多少个器皿,被旁观者使用这几个标志Post 三个平地风波,然后从那个容器中拿出全体应用这一个符号注册过的观察者,挨个通告,这样既解耦,并且只要驾驭这么些符号,在 App 任何岗位都得以监听,也支撑一对多。

累加供给4,中关系的运用 Url 作为标记,那小编就能够形成从前诉求的代码贰个也不用改,只用写接收端的代码就能够兑现上述的急需。

对于这种对外 Api 设计上的需要,大家理应把大旨功效完结了,再逐月优化到想到达的靶子所以先深入分析上边包车型客车急需

5. 构思 Api

因为急需 1 业已涉嫌,达成上传和下载速度监听的基本点正是在 Interceptor 上将每一个须要原有的 RequestBodyResponseBody 替换成重写后的

怎么着识别须求监听进程的央浼?

轮换是粗略,然并不是各类央求都急需监听上传和下载速度,不大概各类央求都替换啊,起初自己想开的是给急需监听进程的乞请生成个标记,然后在 Interceptor 中分析到这一个标志,就证实那么些须求须要监听上传或下载进程,然后就从头交替之

于是乎小编想开最简便易行的措施正是在伸手的时候加二个自定义的 Header ,那样就不要再定义其余的类, Interceptor 遍历全部 Header 开掘有那些自定义 Header ,就足以替换

然则这么并不曾化解供给4,因为这么让顾客比经常呼吁时多了个操作,假诺想让此前的代码具有进程监听功用,就要一个个挨着改,扩大了劳动量,而且以此操作是针对性于自己这几个库而发出的,当客商并不想利用这一个库的时候,会拉拉扯扯到修改在此以前的代码,这样还是扩张了侵入性

既是谈起 EventBus ,那本身就用 伊芙ntBus 的 Api 来规划,顾客只用一行代码,传入二个 标识 和二个 事件 就可以完结上传和下载速度监听,没有错 标志 正是 Url , 事件 正是用于获取进度音讯的 监听器,那样也就满足了 须求 3 的一整套代码实现的必要。

Like this:

ProgressManager.post(标记,事件);

客商调用这一行代码后,作者会将 Url 作为 Key,监听器 作为 value 归入四个大局独一的 Map 中。

等等?说好一对多的啊?所以那么些 value 必需是 List< 监听器 > ,这样就满足了一对多的准则了。

Url 作为标志

三个念头一闪而过,还要什么标志, Url 是独一的, 不就足以看做标识吗!!!

借用 EventBus 思想

干什么把那多少个必要放在一同吗,因为那四个需要让自家想到了 EventBus ,两个阅览者使用同一个标记将本身注册进三个器皿,被观看者使用这一个标志 Post 贰个平地风波,然后从那么些容器中拿出全部应用这几个标识注册过的观看者,挨个公告,那样既解耦,并且只要领悟这些符号,在 App 任何岗位都得以监听,也扶助一对多

加上须求 4,中关系的应用 Url 作为标记,那本身就足以成功此前央浼的代码一个也不用改,只用写接收端的代码就能够达成监听进程的急需

个中如何打招呼监听器?

笔者们把持有需求监听的 Url 的 监听器 都注册进了这些容器,那我们如曾几何时候该去布告 监听器 进程音信吗,当然是在 RequestBody 和 ResponseBody 中初露写入或读取二进制流的时候,因为只有他们第有的时候间知道,读取和写入的年月,今后只供给把对应 Url 的有所 监听器 归入他的 Body 中就足以了。

因为 需要4 中涉嫌,大家并不知道哪些诉求是亟需监听上传或下载进程,哪些是无需的,可是以后我们就能够通过 Url 来辨别,因为大家得以在 Interceptor 中得到 Request 的 Url。

事先大家曾经将 Url 作为 Key 注册进了容器,假使容器里面 Contain 那一个 Url 那正是认证这些央求,是需求监听上传或下载进程的,这大家就给她替换到重写后的 Body 并将监听器传入,重写后的 Body 在发出二进制流的 读取 或 写入 时频频的遍历这一个 Url 的持有 监听器,调用 监听器 的监听方法,并传播进度新闻,就可以进行使用者的翻新逻辑,那就马到功成了。

构思 Api

既是提起 EventBus ,那小编就用 EventBusApi 来设计,客户只用一行代码,传入三个 标记 和一个 事件 就能够实现上传和下载速度监听,没有错 标记 就是 Url , 事件 就是用于获取进程音讯的 监听器,那样也就满意了 需求 3 的一行代码达成的急需

Like this

ProgressManager.post;

客商调用这一行代码后,小编会将 Url 作为 Key,监听器 作为 value 归入一个大局独一的 Map

等等?说好一对多的吧?所以这些 value 必须是 List< 监听器 > ,那样就知足了一对多的尺度了

急需 8 (主线程施行)

以此很简单,使用 Handler.post(Runnable) 在 Runnable 中调用 监听器 的办法就能够了。

=

6 .框架细节优化

=

内部如何打招呼监听器?

笔者们把具备需求监听的 Url监听器 都注册进了那些容器,那大家什么样时候该去通告 监听器 进度新闻吗,当然是在 RequestBodyResponseBody 中初露写入或读取二进制流的时候,因为独有他们第临时间知道,读取和写入的岁月,今后只须要把对应 Url 的所有 监听器 归入他的 Body 中就可以了

因为 需求 4 中关系,大家并不知道哪些央浼是索要监听上传或下载进程,哪些是无需的,不过现在我们就足以由此 Url 来辨别,因为我们能够在 Interceptor 中拿到 RequestUrl

事先咱们已经将 Url 作为 Key 注册进了容器,借使容器里面 Contain 这个 Url 那便是表达那些央浼,是内需监听上传或下载进程的,那我们就给他替换来重写后的 Body 并将监听器传入,重写后的 Body 在发出二进制流的 读取 或 写入 时不停的遍历这几个 Url 的所有 监听器,调用 监听器 的监听方法,并传到进度消息,就足以推行使用者的立异逻辑,那就马到成功了

那些很简短,使用 Handler.postRunnable 中调用 监听器 的点子就足以了

世家都知道 EventBus 注册观望者后,在没有要求经受事件时,需求手动注销,不过使用到自身这些库中,事件的吸取只怕无需如此严格,所感到了免去使用者多余的步骤,小编正是利用 WeakHashMap 取代在此之前的 Map 容器,这个 WeakHashMap 会在 Java虚拟机 回收内存时,找到没被选取的 Key,将此条约整个移除,所以无需手动 remove()

在上头提到客户只供给一行代码,将 Url监听器 出席容器,不过那行代码,或者是在分化线程中被调用的,並且那行代码内的有个别逻辑在十二线程中是不安全的,全体那时小编须要步向线程锁,这一个对于三方库很关键,因为您不可能预知一些顾客的操作

因为笔者在 需求 2 中已经关系,此库只会用 provided 引入 Okhttp ,所以 Okhttp 是不会被打进 aar 包里的,所以一旦使用者在和谐的类型中尚无引进 Okhttp 是会报 NoClassDefFoundError 这几个荒唐的,不过这一个荒唐会让使用者不精通真实的失误原因,让使用者误感觉是这么些库导致的,所以笔者会在库初步化的时候, Class.forName("okhttp3.OkHttpClient"); 假使找不到 Okhttp 的这一个类,表达使用者未有引进 Okhttp ,然后笔者会抛出一个批注非常明晰的荒谬

因为地方提到过笔者会在 Body ,初始读取或写入二进制流时,不断的遍历全体监听器并调用它的监听方法,来达到一对多的一路立异

只是这么 监听器 到达自然数量就能够产出质量难题,並且在遍历时,搞倒霉使用者也会四处的增进新的监听器,在遍历时退换容器的尺寸是便于产生错误的

为此本身在将 List 传入 Body 时,将这个 List.toArray() ,数组分配的是连连的内部存款和储蓄器区域相同的时长是一向的,所以索引效能据有优势,则应用数组来遍历,由于数主管度是定点的,所以也不会冒出遍历时间长度度变化的难题

因为 App 客户可能在前三个速度还没上传或下载完的意况下,继续使用同叁个 Url 开首新的伸手,假设框架使用者在上层不去做去除重复点击的操作,那同一个 Url 就能同不经常候存在多少个正在实行的速度更新,那时就必要有标志符来区分到底是哪位进程音讯(那么些 Url 的享有正在实施的进程更新都会调用在此之前以那一个 Url 注册过的监听器),所以本身在 Body 创造时会将 System.currentTimeMillis() 作为独一 ID ,保存起来,每一趟将进度音讯和 ID 一同传给使用者

实则这些库本来就相比较轻便,达成的着力措施在好多地点都以能一直复制粘贴到的,但因此笔者那样一封装仍旧要比在此以前的方法,轻便优雅十分的多,而写那篇小说的目也是想享受下,如何深入分析要求,以及哪些封装优化三个Mini的库,当然日常也要多读书源码,不断累积和借鉴出色的挂念在文章时灵感才会接连不断,比方本身那个库就是借鉴的 EventBus 的合计,在写代码时要敢于想敢于尝试较于事先分歧的新思索,才会不断升高

Github : 具体达成还得看源码不是? 记得给 Star ✊ 多谢!

Hello 笔者叫Jessyan,若是您心爱作者的篇章,能够在以下平台关怀自己

  • GitHub:
  • 掘金:
  • 简书:
  • 微博:

-- The end

不要手动注销

大家都知道 EventBus 注册观望者后,在没有需求经受事件时,要求手动注销,但是使用到自己那么些库中,事件的抽取只怕不必要这么严刻。

为此为了排除使用者多余的步调,作者正是运用 WeakHashMap 替代在此以前的 Map 容器,那个 WeakHashMap 会在 Java设想机 回收内部存款和储蓄器时,找到没被选取的 Key,将此条目整个移除,所以不供给手动 remove()

-

加锁

在下面提到客商只要求一行代码,将 Url 和 监听器 出席容器,可是那行代码,恐怕是在不一样线程中被调用的,並且那行代码内的有个别逻辑在二十四线程中是不安全的,全部那时作者索要步向线程锁,那一个对于三方库很主要,因为您不能够预感一些客商的操作。

-

向使用者抛出清晰的失实

因为自身在 需求2 中曾经涉嫌,此库只会用 provided 引进 Okhttp ,所以 Okhttp 是不会被挺进 arr 包里的,所以只要使用者在温馨的品种中从未引进 Okhttp 是会报 NoClassDefFoundError 那么些荒唐的,不过这些荒唐会让使用者不清楚真实的失误原因,让使用者误认为是这么些库的导致的,所以作者会在库开端化的时候, Class.forName("okhttp3.OkHttpClient");

 如若找不到 Okhttp 的那么些类,表达使用者未有引进 Okhttp ,然后笔者会抛出贰个表明特别清楚的荒谬。

加强质量

因为上边提到过小编会在 Body ,开始读取或写入二进制流时,不断的遍历全部监听器并调用它的监听方法,来到达一对多的联手革新。

然则如此 监听器 达到一定数额就相会世品质难题,并且在遍历时,搞不好使用者也会,不断的丰硕新的监听器,在遍历时改造容器的长短是轻巧生出错误的。

因而笔者在将 List 传入 Body 时,将这一个 List.toArray() ,数组分配的是连接的内部存款和储蓄器区域还要长度是长久的,所以索引功用占领优势,则应用数组来遍历,由于数老董度是牢固的,所以也不会冒出遍历时间长度度变化的主题素材。

分别同多少个Url的多少个进度

因为 App 客户只怕在前三个进度还没上传或下载完的事态下,继续运用同贰个 Url 开始新的伏乞,如若框架使用者在上层不去做去除重复点击的操作。

那同多少个 Url 就能够同有时间设有八个正在实践的快慢更新,那时就须求有标志符来区分到底是哪些进程消息(那一个 Url 的具有正在实行的速度更新都会调用在此之前以这么些 Url 注册过的监听器),所以本人在 Body ,创设时会将 System.current提姆eMillis() 作为独一 ID ,保存起来,每一次将进度音讯和 Id 一齐传给使用者。

7. 总结

事实上那些库本来就相比较轻易,达成的着力措施在许多地方都以能复制粘贴到的,但经过自家如此一封装依旧要比此前的主意,轻便优雅十分的多,而写那篇文章的目也是想分享下:

怎么分析须求,以及怎么着封装优化二个小型的库,当然日常也要多读书源码,不断储存和借鉴优良的思量在编写时灵感才会接踵而来,例如自身那一个库正是借鉴的 EventBus 的思维,在写代码时要敢于想敢于尝试较于事先分歧的新构思,才会不断升高。

Github : 具体落到实处还得看源码不是? 记得给 Star ✊ 多谢!

Hello 小编叫Jessyan,假若你喜欢自个儿的作品,能够在偏下平台关切本身

GitHub: 

掘金: 

简书: 

微博: 

-- The end

假诺你有好的篇章想和豪门分享招待投稿,直接向本身投递小说链接就可以。

图片 3

图片 4

本文由王中王开奖结果发布于网络编程,转载请注明出处:Glide下载上传进程监听

关键词:

上一篇:Glide下载上传进程监听
下一篇:没有了