我们看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等也都会用它
在内存不足的时候,对自己占用的进行清理。
最后用图来总结吧,没有捋顺的童鞋可以参考看看,有其他疑问的,咱评论区见了。