android----Glide辅助文档

这是一篇为阅读glide的帮助文章,不细讲,意在说明一些类的功能和整个流程。

 

在看这篇前,请先去看下面的链接

细讲资源:

https://blog.csdn.net/guolin_blog/article/details/53759439

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2018/0403/9555.html

https://www.jianshu.com/p/5c8ce241199e

 

介绍:

Glide是一个的图片加载框架,使得我们可以在Android平台上以极度简单的方式加载和展示图片。

 

简述其功能:

Glide 帮助我们有简洁的代码,完成了对图片网络访问、内缓存、磁盘缓存、不同形式的展示。

我们按照上图的链式调用顺序分析其功能:

1.  完成glide的前提条件:glide.with()

首先要解决如何让glide框架,能够与展示的它容器(eg,activity)共存亡。不能让容器都被销毁了,我们还持有glide对象。这样就浪费内存了。

glide.with()帮助我们向其容器加入一个fragment,由于监听容器的生命周期,从而决定是否暂停或销毁glide. 最后放回给我们一个RequestManager,顾名思义请求的管理类。我们分析其成员变量。

      

       我们可以看到其几个重要的成员变量。

lifecycle ---有与监听容器状态的改变,并调用自己重写的onStart、onStop、onDestory.

       treeNode ---响应容器的暂停和恢复请求,为其提供操作请求的方法。

       requestTracker --- 实际去操作请求的对象。扩充下:如何控制的???requestTracker中有一个成员变量requests,存放着                                       所有所有的请求,遍历requests,找到isRunning的请求。 改变其状态。并将其放入pendingRequests.

       glide ---这个是个重器。

       optionsApplier ---调用的options,将传入builder(DrawableTypeRequest)。

       options ---让开发者重写,意在拿到builder(DrawableTypeRequest),做一些操作。

       小结1:RequestManager为glide提供同步容器的服务。并且

2. 前期准备:load()

对于load前期的准备,就是创建能处理请求的工具类。

节点C: 准备分为两部分

先分析fromString()

节点B

在RequestManager中,创建了满足不同类型请求的不同工具类,然后将这些工具封装到DraeableTypeRequest中。

下面介绍下工具类的功能

节点A:这个节点用于介绍工具类功能。

  1. streamModelLoader
  2. fileDescriptorModelLoader

modelClass---这个是你用什么类型请求图片。系统支持:StringUriFileIntegerURLbyte、自定义。(我们这里以String为例)

节点 A1和A2差不多所以只分析A1:

创建streamModelLoader:

 这里下剧透其功能:帮助请求访问网络,其实现类为HttpUrlFetcher.

下面分析其具体的创建过程,这个比较重要,因为创建它的同时,也有很多类被创建,对后面读代码有很大的影响。

在进入buildStreamModelLoader,最终到达上图。发现其在创建streamModelLoader前先去创建Glide,

glide.get方法:

进入buider.createGlide():

节点F:下图创建sourceServicediskCacheService.

这里创建了serceService、diskCacheService、bitmapPool???

memoryCache---内存缓存。

disCacheFactory---创建磁盘缓存的工厂。

engine----驱动引擎。???

decodeFormat----设置的rgb

然后将上述放入new glide中

                             图1.0

                            图 2.0

上图是glide的内部创建的东西,不要太多。这里直接剧透,这些东西其实我们可以将其看成两张表单,这两张表单的作用:获取资源的转换对象。

先说下glide中不同的类型转换:

第一种表registry(图2.0与网络有关的转换,由于我们会有不同类型的请求(String、Url、file等)会通过网络来拿到图片数据,此时图片数据的我们想用什么类型来接受尼。系统给了两种接受类型:inputStream与PracelFileDescriptor。默认为inputStream,其转换类为httpUrlFetcher,而PracelFileDescriptor对应的为null,估计是留给自己实现的。

第二张表:(图1.0)

dataLoadProviderRegistry.register表:将图片的缓存、网络等数据转换为bitmap、Gif、file等类型---俗称转码与解码。其转换类多就不细说。但是有一个共同的父类DataLoadProvider.

streamModelLoaderfileDescriptorModelLoader属于第一张表的转换的类

streamModelLoader-----httpUrlFetcher(不同类型的请求,对应不同参数的httpUrlFetcher, 通过httpUrlFetcher网络访问获得InputStream类型的图片数据)

fileDescriptorModelLoader-----null

 

PracelFileDescriptor:操作文件流的工具类,详细问度娘。

 

        上面我们分析了节点创建DraeableTypeRequest所需的类,接下来看其具体创建了些什么???

        进入红色箭头

      

节点I:

从上图可以看到最后返回FixedLoadProvider,传入三个对象,modelLoader、transcoder、dataLoadProvider.

        modelLoader---用于主要用于网络请求( streamModelLoader实现类httpUrlFethcer)

        dataLoadProvider----用于图片的解码 (实现类ImageVideoGifDrawableLoadProvider)

        transcoder-----用于图片转码。  

        FixedLoadProvider-----网络访问和转解码图片的总工具类 

  最后 将在DrawableTypeRequest 中创建的对象FixedLoadProvider传给GenericRequestBuider的loadProvider变量。这里我们顺便来了解下GenericRequestBuider:

       

这个类我们可以理解为一个请求的基本类。那么一个请求应该含有什么基本条件呢???我们可以看上图其构造函数。

需要context、modelClass(请求类型)、transcodeClass(GlideDrawable)、glide(操作类)、requsetTracker(请求队列)、lifecycle(周期回调函数)、LoadProvider(网络访问和转解码图片的总工具类)。

回到节点C

分析load()

将请求信息交给其父类(GenericRequestBuilder)保存。

为啥要给其父类????

小结:我们知道了对于一个请求而言,前期需要准备写什么???

  1. 系统需要单例创建glide,生成请求类型与图片类型对应的转换表单,创建工具类(一次)
  2. 对于一个请求来说,创建一个DrawableTypeRequest的类型抽象类。其持有

网络访问对象(streamModelLoader)、fileDescriptorModelLoader(null)、optionsApplier(暴露自己给开发者)。

  1. 将请求信息交给其父类GenericRequestBuilder保存。

体现类的多态性。

        最后说下其关系:

         GenericRequestBuilder(爷爷辈)--》BitmapRequsetBuilder、GifRequsetBuilder等父辈------》BitmapTypeRequest、GifTypeRequset等子辈------》DrawableTypeRequest

3. 完成请求:lnto()

glide.buildImageViewTarget的作用:

当我们的请求处理完成返回给我们bitmap,gif等类型的数据,我们如何让其适配我们的view呢?这个方法就是解决了。

简单不细讲。

进入GenericRequestBuilder .into

requsetTracker.runRequest

上面可以看出来开始处理请求了。requestsTracker存储请求的工具类。

(GenericRequest)request.begin(不解释,详情看前面链接)

 

 

onSizeReady()

节点:J

前面是设置宽高的省略了。从上图437行开始。

不知道你们是否还记得loadProvider的创建-------节点I

可以知道

         loadProvider----FixedLoadProvider工具箱

modelLoader----ImageVideoModelLoader其持有httpUrlFetcher用于网络访问

         dataFetcher---- ImageVideoFetcher ,其是ImageVideoModelLoader的内部类,完成具体的网络访问。

 

engine.load()

节点E:

上图:

149行:EngineKey----由于标识图片资源的。如身份证。

153行、162行通过EngineKey分别查询内存缓存和闪存是否有资源,找着任意一个都行。

闪存-----存储的是正在被用的图片。(Map<key,WeakReference>)

内存缓存-----近期被用到的图片,但现在没用到。(LruResourceCache

 

180-186行 前面两个缓存都没找到,到达此处。我们就只能从磁盘缓存或者网络来拿到数据了, 由于二者都比较耗时,于是开启任务。

EngineJob-----劳动者(苦工)

DecodeJob-----转解码(工具)

EngineRunnable-------任务(事件)

我们就看到苦工拿着工具去处理任务了。

提下EngineJob的具有的功能:

this里面有6个参数,我们讲解下disCacheService、sourceService。其它参数是去设置其属性的,体现不了其功能。

节点H:

disCacheService、sourceService创建地方------节点F

从节点中看到这两个的具体实现类为线程池。

功能:

disCacheService-----提供1个线程执行任务,glide会用这些线程执行检查磁盘缓存的任务。

sourceService-------提供n个线程池执行任务,glide会用这些线程执行网络访问的任务(n与具体的CPU参数有关)

于是我们知道了EngineJob的工作提供检验磁盘缓存和网络访问的线程池(抽象理解为苦力)。

 

接下来我们进入EngineRunnable.run看看苦工是如何处理的。

节点D:用于回到上图EngineRunnable.run方法

没啥好说的,进入58行 decode()

这里有个if----isDecodingFromCache就是判断磁盘缓存中是否有任务需要的数据。

新创建的任务stage=CACHE。于是我们进入了decodeFromCache去磁盘找数据了。

108行和116行的方法中都是调用loadFromCache去磁盘中找数据,不同的是其传入的key不同,分别是resultKey(获取图片)和resultKey.getOriginalKey()(获取原始图片)。

下面说下磁盘缓存策略------由于我们对图片会有不同的设置(节点E:149行生成EngineKey的参数)都会导致key的值不同。

都会导致我们磁盘缓存。但是这样就有个问题了,曾经有一个Url,通过网络获得了图片,并磁盘缓存了。但是现在这个Url对应的图片,我想让其展示在一个更大的地方,那我们还需要在去网络访问吗???当然不用了。因为glide在拿到了网络中的原始图片后,会将原始图片在磁盘缓存中缓存一份。然后才会将图片转换为我们需要的图片。所以当我们下次在去访问时,发现是同一个url,直接从磁盘缓存中取然后转换为此时需要的图片类型,就不用再网络访问了。

 

所有新创建的请求(stage=CACHE)都会去检查磁盘缓存,不管是否有数据都会返回给回到节点D 58行。

下面说如果磁盘缓存没有要的数据,返回给我们为null时,从节点D中我们可以看到其执行了74行。

此时的isDecodingFromCache返回true。 于是我们改变了任务状态为SOURCE.并将认为交给manager.submitFromCache

发现是EngineRunnable的内部接口。其实现在EngineJob(苦工)中.

发现任务交接了sourceService。

由前面的节点H可以知道,sourceService为我们提供了线程去执行其任务。这样我们有回到节点D:用于回到上图EngineRunnable.run方法中执行decode()。

此时if中为false.

我们开始了网络访问分支。进入decodeFromSource

上图170行

Fetcher的创建---节点J

知道fetcher-----imageVideoFetcher

imageVideoFetcher.loadData()

有节点J知道streamFetcher-----httpUrlFetcher.这时我们终于到达了网络访问的具体实现类,同时也到达了终点站。

这只是一篇帮助文档。希望对你有帮助。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值