没有合适的资源?快使用搜索试试~ 我知道了~
首页提升阅读能力:Glide源码深度解析
提升阅读能力:Glide源码深度解析
需积分: 9 1 下载量 47 浏览量
更新于2024-07-15
收藏 3.48MB PDF 举报
本文是一份针对2019年一线互联网公司Android面试的高频问题总结,特别是关于第三方源码Glide的深度解析。Glide是一个流行的Android图片加载库,面试者通常会被问及其加载、缓存机制,以及LRU(Least Recently Used,最近最少使用)算法的实现,尤其是在设计自己的大图加载框架时如何应用LRUCache原理。 阅读源码是面试中的一个重要环节,作者分享了自己的阅读源码经验,强调了阅读策略:抽丝剥茧和点到即止。这意味着在分析源码时,应专注于一个特定的功能点,理解其实现逻辑,而不是力求弄懂每行代码的具体含义。由于Glide的复杂度极高,建议读者关注整体流程而非细节,首先把握核心功能如如何通过`Glide.with(this).load(url).into(imageView)`加载网络图片并显示在ImageView上。 文章还提到了阅读源码的准备工作,包括下载Glide的源码,这对于深入理解其内部机制至关重要。如果Glide是通过Gradle依赖引入项目的,源码应该已经包含在内。接下来的文章将逐步深入探讨Glide的源码细节,以便全面理解其图片加载机制。 对于准备参加面试的Android开发者来说,掌握Glide的工作原理,理解如何使用LRU缓存策略,以及如何高效阅读源码,将大大提高通过技术面试的概率。通过本文的学习,不仅可以提升技术能力,还能为实际项目开发提供宝贵的经验。
资源详情
资源推荐
![](https://csdnimg.cn/release/download_crawler_static/13090443/bg10.jpg)
super.fallback(resourceId);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> error(int resourceId) {
super.error(resourceId);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> error(Drawable drawable) {
super.error(drawable);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> listener(
RequestListener<? super ModelType, GlideDrawable> requestListener) {
super.listener(requestListener);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> diskCacheStrategy(DiskCacheStrategy strategy)
{
super.diskCacheStrategy(strategy);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> skipMemoryCache(boolean skip) {
super.skipMemoryCache(skip);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> override(int width, int height) {
super.override(width, height);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> sourceEncoder(Encoder<ImageVideoWrapper>
sourceEncoder) {
![](https://csdnimg.cn/release/download_crawler_static/13090443/bg11.jpg)
super.sourceEncoder(sourceEncoder);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> dontTransform() {
super.dontTransform();
return this;
}
@Override
public DrawableRequestBuilder<ModelType> signature(Key signature) {
super.signature(signature);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> load(ModelType model) {
super.load(model);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> clone() {
return (DrawableRequestBuilder<ModelType>) super.clone();
}
@Override
public Target<GlideDrawable> into(ImageView view) {
return super.into(view);
}
@Override
void applyFitCenter() {
fitCenter();
}
@Override
void applyCenterCrop() {
centerCrop();
}
}
DrawableRequestBuilder 中有很多个方法,这些方法其实就是 Glide 绝大多数的 API 了。里面
有 不 少 我 们 在 上 篇 文 章 中 已 经 用 过 了 , 比 如 说 placeholder() 方 法 、 error() 方 法 、
![](https://csdnimg.cn/release/download_crawler_static/13090443/bg12.jpg)
diskCacheStrategy()方法、override()方法等。当然还有很多暂时还没用到的 API,我们会在后
面的文章当中学习。
到 这 里 , 第 二 步 load() 方 法 也 就 分 析 结 束 了 。 为 什 么 呢 ? 因 为 你 会 发 现
DrawableRequestBuilder 类中有一个 into()方法(上述代码第 220 行),也就是说,最终 load()
方法返回的其实就是一个 DrawableTypeRequest 对象。那么接下来我们就要进行第三步了,
分析 into()方法中的逻辑。
3. into()
如果说前面两步都是在准备开胃小菜的话,那么现在终于要进入主菜了,因为 into()方法也
是整个 Glide 图片加载流程中逻辑最复杂的地方。
不过从刚才的代码来看,into()方法中并没有任何逻辑,只有一句 super.into(view)。那么很显
然,into()方法的具体逻辑都是在 DrawableRequestBuilder 的父类当中了。
DrawableRequestBuilder 的 父 类 是 GenericRequestBuilder , 我 们 来 看 一 下
GenericRequestBuilder 类中的 into()方法,如下所示:
public Target<TranscodeType> into(ImageView view) {
Util.assertMainThread();
if (view == null) {
throw new IllegalArgumentException("You must pass in a non null View");
}
if (!isTransformationSet && view.getScaleType() != null) {
switch (view.getScaleType()) {
case CENTER_CROP:
applyCenterCrop();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
applyFitCenter();
break;
//$CASES-OMITTED$
default:
// Do nothing.
}
}
return into(glide.buildImageViewTarget(view, transcodeClass));
}
这里前面一大堆的判断逻辑我们都可以先不用管,等到后面文章讲 transform 的时候会再进
行 解 释 , 现 在 我 们 只 需 要 关 注 最 后 一 行 代 码 。 最 后 一 行 代 码 先 是 调 用 了
glide.buildImageViewTarget()方法,这个方法会构建出一个 Target 对象,Target 对象则是用来
最终展示图片用的,如果我们跟进去的话会看到如下代码:
![](https://csdnimg.cn/release/download_crawler_static/13090443/bg13.jpg)
<R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}
这里其实又是调用了 ImageViewTargetFactory 的 buildTarget()方法,我们继续跟进去,代码如
下所示:
public class ImageViewTargetFactory {
@SuppressWarnings("unchecked")
public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
if (GlideDrawable.class.isAssignableFrom(clazz)) {
return (Target<Z>) new GlideDrawableImageViewTarget(view);
} else if (Bitmap.class.equals(clazz)) {
return (Target<Z>) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (Target<Z>) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException("Unhandled class: " + clazz
+ ", try .as*(Class).transcode(ResourceTranscoder)");
}
}
}
可以看到,在 buildTarget()方法中会根据传入的 class 参数来构建不同的 Target 对象。那如果
你要分析这个 class 参数是从哪儿传过来的,这可有得你分析了,简单起见我直接帮大家梳
理清楚。这个 class 参数其实基本上只有两种情况,如果你在使用 Glide 加载图片的时候调用
了 asBitmap()方法,那么这里就会构建出 BitmapImageViewTarget 对象,否则的话构建的都
是 GlideDrawableImageViewTarget 对象。至于上述代码中的 DrawableImageViewTarget 对象,
这个通常都是用不到的,我们可以暂时不用管它。
也 就 是 说 , 通 过 glide.buildImageViewTarget() 方 法 , 我 们 构 建 出 了 一 个
GlideDrawableImageViewTarget 对象。那现在回到刚才 into()方法的最后一行,可以看到,这
里又将这个参数传入到了 GenericRequestBuilder 另一个接收 Target 对象的 into()方法当中了。
我们来看一下这个 into()方法的源码:
public <Y extends Target<TranscodeType>> Y into(Y target) {
Util.assertMainThread();
if (target == null) {
throw new IllegalArgumentException("You must pass in a non null Target");
}
if (!isModelSet) {
throw new IllegalArgumentException("You must first set a model (try #load())");
}
Request previous = target.getRequest();
![](https://csdnimg.cn/release/download_crawler_static/13090443/bg14.jpg)
if (previous != null) {
previous.clear();
requestTracker.removeRequest(previous);
previous.recycle();
}
Request request = buildRequest(target);
target.setRequest(request);
lifecycle.addListener(target);
requestTracker.runRequest(request);
return target;
}
这里我们还是只抓核心代码,其实只有两行是最关键的,第 15 行调用 buildRequest()方法构
建出了一个 Request 对象,还有第 18 行来执行这个 Request。
Request 是用来发出加载图片请求的,它是 Glide 中非常关键的一个组件。我们先来看
buildRequest()方法是如何构建 Request 对象的:
private Request buildRequest(Target<TranscodeType> target) {
if (priority == null) {
priority = Priority.NORMAL;
}
return buildRequestRecursive(target, null);
}
private Request buildRequestRecursive(Target<TranscodeType> target,
ThumbnailRequestCoordinator parentCoordinator) {
if (thumbnailRequestBuilder != null) {
if (isThumbnailBuilt) {
throw new IllegalStateException("You cannot use a request as both the main
request and a thumbnail, "
+ "consider using clone() on the request(s) passed to thumbnail()");
}
// Recursive case: contains a potentially recursive thumbnail request builder.
if (thumbnailRequestBuilder.animationFactory.equals(NoAnimation.getFactory())) {
thumbnailRequestBuilder.animationFactory = animationFactory;
}
if (thumbnailRequestBuilder.priority == null) {
thumbnailRequestBuilder.priority = getThumbnailPriority();
}
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !Util.isValidDimensions(thumbnailRequestBuilder.overrideWidth,
thumbnailRequestBuilder.overrideHeight)) {
剩余165页未读,继续阅读
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://profile-avatar.csdnimg.cn/56597bc0e2b342528182c1f23153ec6b_alleria123.jpg!1)
alleria123
- 粉丝: 2
- 资源: 2
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![](https://csdnimg.cn/release/wenkucmsfe/public/img/voice.245cc511.png)
最新资源
- Vue实现iOS原生Picker组件:详细解析与实现思路
- Arduino蓝牙小车:参数调试与功能控制
- 百度Java面试精华:200页精选资源涵盖核心知识点
- Swift使用CoreData填坑指南:CoreData在Swift 3.0的变化
- 微距离无线充电器创新设计及其实验探索
- MTK Android平台开发全攻略:44步详解流程
- RecyclerView全面解析:替代ListView的新选择
- Android开发:自动适配中英文键盘解决方案
- Android调用WebService接口教程
- Android开发:BitmapUtil图片处理全解析与实例
- Android多线程断点续传实现详解
- PCA算法在人脸识别会议签到系统中的应用
- EventBus 3.0:Android事件总线详解与实战应用
- Android FileUtil:全面解析文件操作实用技巧与实例
- RecyclerView添加头部和尾部实战教程
- Android实现微博滑动固定顶部栏实战与优化
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035111.png)
安全验证
文档复制为VIP权益,开通VIP直接复制
![](https://csdnimg.cn/release/wenkucmsfe/public/img/green-success.6a4acb44.png)