Android 图片加载框架Glide源码详解

我们看Glide的源码从Glide类入手,使用的时候我们先调用的with方法,源码中with有3个多载的方法:下图翻译过来就是activity用FragmentActivity Applicationcontext用 with(Context)还有一个with(View)的
在这里插入图片描述
殊途同归,最后都是调用了getRetriever(context).get(context),我们看看最后的get(context)方法 ,如下图, 这就大致分成两类一种是ApplicationContext, 一种是activity,fragment ,两种lifecycle生命周期,下图是证明:
在这里插入图片描述
在这里插入图片描述
为什么要区分Applicationlifecycler和Activitylifecycler 呢?
在Glide中,区分Application Lifecycle和Activity Lifecycle主要是为了更好地管理图像加载和缓存的策略。

Application Lifecycle:在Android应用程序中,Application Lifecycle指的是从应用程序启动到关闭的整个生命周期。在这个生命周期中,Glide可以根据应用程序的整体状态来调整其行为。例如,当应用程序处于后台时,Glide可以减少图像加载的频率或暂停加载,以节省资源和电量。而在应用程序重新进入前台时,Glide可以恢复正常的加载行为。
Activity Lifecycle:Activity Lifecycle指的是一个Activity从启动到销毁的周期。在这个生命周期中,Glide可以与Activity的各个生命周期回调方法进行交互,以便在适当的时机加载和显示图像。例如,当Activity在用户面前时(onResume()调用后),Glide可以在该时机加载并显示图像。而在Activity被用户离开时(onPause()调用后),Glide可以暂停加载或释放一些资源。
通过区分这两个生命周期,Glide可以更精细地控制图像加载和缓存的行为,以适应不同场景和应用程序需求。这有助于提高应用程序的性能、节省资源并提高用户体验。

同时glide的初始化也是在这里getRetriever方法中完成的
在这里插入图片描述
在这里插入图片描述

从图上我们也可以看出来with 方法返回的是RequestManager, 里面有一个TargetTracker 跟踪view target的 ,每当RequestManage生命周期变化时,通知各个view。
在这里插入图片描述
在这里插入图片描述
现在是不是能想到,之前聊的lifecycler两种生命周期和它对上了,Application和activity等他们的生命周期会调用manager的,manager再通知各个view,贯通了整个框架。给你们看一下添加的listener
在这里插入图片描述

RequestManager集合了glide的要用的各种类,对Request进行管理,其中里面的load方法返回的是RequestBuilder,这里的load实际上还是调用RequestBuilder里面的load
在这里插入图片描述
load的方法还是挺空的,重点是赋值这个model 图片地址。
在这里插入图片描述

从下图可以看出,RequestBuilder这个类才是Builder设计模式的主类,我们使用中最后的into方法返回的是Target,大部分逻辑都在这个方法里面了, buildRequest就是重点,

在这里插入图片描述

在这里插入图片描述
然后走的是obtainRequest
在这里插入图片描述
SingleRequest.obtain
在这里插入图片描述
SingleRequest获得后,在begin方法中
在这里插入图片描述
有个onSizeReady
在这里插入图片描述
主角登场,engine.load方法。
在这里插入图片描述
里面有glide加载缓存的逻辑
在这里插入图片描述
下图可以看到是先加载内存中的处理过的resource,里面是一个hashmap维护的key resource 键值对的缓存,第二个就是采取了lru算法的采用linkedhashmap的内存数据
在这里插入图片描述
然后是调用了waitForExistingOrStartNewJob方法,开始decodeJob 解码工作
在这里插入图片描述
runWrapped()方法, runGenerators方法, currentGenerator.startNext()
在这里插入图片描述
值得看的是currentGenerate是下图中3个的哪一个呢,从逻辑上看3个会依次遍历,分别是先处理过的resource缓存,然后是data缓存,最后是Source网络加载, 这也是glide的三级缓存。我们只讲一个SourceGenerator,里面也有下载图片的modelloader,其他两个的逻辑差不多,不再赘述了。下面就要开始讲根据model,data找modelloader的逻辑了,做好心理准备,不简单,网上大都是一笔带过(因为他们也弄不清,的确有点复杂,绕来绕去),好不容易全网找到一篇,不知道是他的版本旧的,还是他理解的不对,珍惜吧,我认为是全篇最难的地方了。

在这里插入图片描述
3个也都会调用loadData.fetcher.loadData,重点是找到这个loadData
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
handles 过滤筛选出可以处理我们数据类型model的modelloader ,比如我们图片用的是https的String
在这里插入图片描述
String的有3个,但如果你是http开头的网络url的话就只有StringLoader.Streamfactory了,可以看他们3个各种的handles
在这里插入图片描述
还没完,用Uri InputStream 来代替执行
在这里插入图片描述
有5个,而符合我们http或https的就只有append(Uri.class, InputStream.class, new UrlUriLoader.StreamFactory())了
在这里插入图片描述
在这里插入图片描述
又转为GlideUrl.class, InputStream.class,我们再去工厂里面找,经过三次我们才真正找到 HttpGlideUrlLoader.Factory()

在这里插入图片描述
想起前面sourceGenerate 的 loaddata.fetcher.loaddata没有,就是这个HttpUrlFetcher
在这里插入图片描述
下载图片的找到了,拿到数据之后的data的回调就是listener来做了,比较简单就不说了,至此难点讲完了。
在这里插入图片描述
然后我们跳回SingleRequest类中

然后你会发现这个begin是由 RequestManager.into方法中的requestManager.track(target, request);发起的
在这里插入图片描述
在这里插入图片描述

随后我们看一下as相关的方法,有三个,其实是两个GifDrawable和drawable是一类,还有一类是bitmap,那么glide为什么将drawable和bitmap 分开呢
在这里插入图片描述

看下图,因为glide把两种分成了两个类target view,view的setImageBitmap 和setImageDrawable两个不同的方法加载Resource。

在这里插入图片描述

再有就是RequestBuilder关于apply函数加载options
RequestOptions options = new RequestOptions()

            .placeholder(R.mipmap.loading)                //加载成功之前占位图

            .error(R.mipmap.loading)                    //加载错误之后的错误图

            .override(400,400)                                //指定图片的尺寸

            //指定图片的缩放类型为fitCenter (等比例缩放图片,宽或者是高等于ImageView的宽或者是高。)

            .fitCenter()

            //指定图片的缩放类型为centerCrop (等比例缩放图片,直到图片的狂高都大于等于ImageView的宽度,然后截取中间的显示。)

            .centerCrop()

            .circleCrop()//指定图片的缩放类型为centerCrop (圆形)

            .skipMemoryCache(true)                            //跳过内存缓存

            .diskCacheStrategy(DiskCacheStrategy.ALL)        //缓存所有版本的图像

            .diskCacheStrategy(DiskCacheStrategy.NONE)        //跳过磁盘缓存

            .diskCacheStrategy(DiskCacheStrategy.DATA)        //只缓存原来分辨率的图片

            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)    //只缓存最终的图片

             .dontTransform()  //禁用图形变换功能,这个方法时全局的,导致其他地方的图片也不可进行图形变换了,慎用.

            .dontAnimate();//跳过动画

Glide还实现了ComponentCallbacks2接口,这个是内存监测的,我们的Activity等也都会用它
在这里插入图片描述
在内存不足的时候,对自己占用的进行清理。
在这里插入图片描述
最后用图来总结吧,没有捋顺的童鞋可以参考看看,有其他疑问的,咱评论区见了。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值