Android进阶——源码分析之图片加载框架Glide

前言

源码阅读不是一件简单的事情,每次都要花费很长时间来梳理其内部的原理,所以有朋友觉得看一遍看不懂,那很正常,接下来就是考验你耐心的时候。学习源码的目的是:学习它好的地方,吸收起来作为我们项目的开发。作为你想进阶成跟别人有优势的程序员,那么阅读代码是你的基本功,懂得提取别人优秀的代码,进行修改成为你的代码,那就是你牛逼的地方,所以还是静下心来看看源代码吧。当然,阅读代码也不要做到只见树木,不见森林

Glide主要特点

  • 支持Memory和Disk图片缓存
  • 支持gif和webp格式图片
  • 根据Activity/Fragment自动管理其生命周期
  • 使用Bitmap Pool可以使Bitmap复用
  • 对于回收的Bitmap会主动调用recycle,减小系统回收压力

Glide的分析流程

Glide图片加载只需要简单的一句链式调用即可高效的加载我们的图片,那么其源码的分析流程也是通过以下的三个方法进行分析

1
2
3
Glide.with(context)
.load(url)
.into(imageView);

Glide的with源码分析

一、with源码中实现原理

我们可以通过with的源码看出,with重载方法很多,可以兼容Activity、Fragment、Application等,这里我们主要以Activity来分析,其他的源码分析大同小异,其with方法实现的主要原理如下

这里写图片描述

二、with源码中涉及到的类

  • RequestManagerRetriever:是关联Activity与RequestManager的使者类
  • RequestManager:是管理和启动Glide的请求类
  • RequestManagerFragment:是一个Fragment
  • ActivityFragmentLifecycle:生命周期接口

三、with源码分析

with源码所做的事情

  • 将传进来的Activity和RequestManager关联起来
  • 将Activity的生命周期和RequestManager的生命周期关联起来

with是如何实现Activity和RequestManager关联起来的?首先进入with源码,按追踪步数阅读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public static RequestManager with(Context context) {
//第一步:拿到RequestManagerRetriever单例
RequestManagerRetriever retriever = RequestManagerRetriever.get();
//第二步:通过RequestManagerRetriever拿到RequestManager,追踪下去
return retriever.get(context);
}
public RequestManager get(Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
//第三步:根据传进来不同的参数,进行对应的方法去获得RequestManager,追踪下去
return get((Activity) context);
} else if (context instanceof ContextWrapper) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public RequestManager get(Activity activity) {
if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
//这里是做线程的判断和和版本的兼容
return get(activity.getApplicationContext());
} else {
//断言:Activity是否被销毁
assertNotDestroyed(activity);
//获取Activity中的FragmentManager,为后面将隐藏的Fragment依附于Activity上做准备,这里不做分析
android.app.FragmentManager fm = activity.getFragmentManager();
//第四步:根据传进的Activity和FragmentManager,进行对应的方法去获得RequestManager,追踪下去
return fragmentGet(activity, fm);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
//获取隐藏的Fragment
RequestManagerFragment current = getRequestManagerFragment(fm);
//获取当前RequestManager
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
//第五步:如果为空则创建出新的RequestManager,将Activity和生命周期作为参数传递进去
//那么这样子就关联起了Activity与RequestManager
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
//设置当前RequestManager
current.setRequestManager(requestManager);
}
return requestManager;
}

其实上面连贯起来是非常简单的一段代码,那么它们是如何将Activity的生命周期和RequestManager的生命周期关联起来的?我们刚才也分析过,其生命周期的传递过程是由Activity->Fragment->RequestManager,那么这样的一个传递过程是如何实现的呢?

首先当Activity生命周期发生改变时,就会在Fragment中调用相应的方法,我们上面有看到通过getRequestManagerFragment方法,来获取Fragment的,追踪其代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
//它是在这里直接创建出新的Fragment,追踪下去
current = new RequestManagerFragment();
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}

来到RequestManagerFragment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class RequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public RequestManagerFragment() {
//调用自身的构造方法,追踪下去
this(new ActivityFragmentLifecycle());
}
// For testing only.
@SuppressLint("ValidFragment")
RequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
//赋值
this.lifecycle = lifecycle;
}
//根据Activity传进来的不同生命周期方法,调用自身lifecycle的回调方法
//我们上面也知道,这个lifecycle已经传递给了RequestManager
//那么它就会回调RequestManager中对应的lifecycle的回调方法
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
}
}

目前,生命周期的回调方法已经从Fragment传到RequestManager类中的lifecycle回调,我们上面也分析到创建出新的RequestManager中时,我们进入这个构造方法,看看具体做了什么事情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class RequestManager implements LifecycleListener {
private final Lifecycle lifecycle;
public RequestManager(Context context, Lifecycle lifecycle, RequestManagerTreeNode treeNode) {
//第一步:调用自身的构造方法,追踪下去
this(context, lifecycle, treeNode, new RequestTracker(), new ConnectivityMonitorFactory());
}
RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
//参数的赋值,将Fragment中的lifecycle传递进来
this.context = context.getApplicationContext();
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.glide = Glide.get(context);
this.optionsApplier = new OptionsApplier();
ConnectivityMonitor connectivityMonitor = factory.build(context,
new RequestManagerConnectivityListener(requestTracker));
if (Util.isOnBackgroundThread()) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//第二步:设置lifecycle的接口回调
lifecycle.addListener(RequestManager.this);
}
});
} else {
//第二步:设置lifecycle的接口回调
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
}
......
//第三步:由于RequestManager已经实现了LifecycleListener,也设置好了lifecycle的接口回调
//那么当有接口方法回调的时候,就会执行对应的方法,也就是Activity发生变化通知Fragment,Fragment通知到这里来
@Override
public void onStart() {
//第四步:根据不同的生命周期,执行不同的Glide请求,这里就不继续分析下去
resumeRequests();
}
@Override
public void onStop() {
pauseRequests();
}
@Override
public void onDestroy() {
requestTracker.clearRequests();
}
}

那么上面涉及到的LifecycleListener,其实就是生命周期的回调接口

1
2
3
4
5
public interface LifecycleListener {
void onStart();
void onStop();
void onDestroy();
}

Glide的load源码分析

一、load源码分析

load方法主要是创建DrawableTypeRequest,并将记录相关的uri等数据供后续使用,按追踪步数阅读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public DrawableTypeRequest<String> load(String string) {
//第一步:记录有关对应的参数,最终转成DrawableTypeRequest
return (DrawableTypeRequest<String>) fromString().load(string);
}
public DrawableTypeRequest<String> fromString() {
return loadGeneric(String.class);
}
public DrawableTypeRequest<Uri> load(Uri uri) {
return (DrawableTypeRequest<Uri>) fromUri().load(uri);
}
public DrawableTypeRequest<Uri> fromUri() {
return loadGeneric(Uri.class);
}
public DrawableTypeRequest<File> load(File file) {
return (DrawableTypeRequest<File>) fromFile().load(file);
}
public DrawableTypeRequest<File> fromFile() {
return loadGeneric(File.class);
}
public DrawableTypeRequest<Integer> load(Integer resourceId) {
return (DrawableTypeRequest<Integer>) fromResource().load(resourceId);
}
public DrawableTypeRequest<Integer> fromResource() {
return (DrawableTypeRequest<Integer>) loadGeneric(Integer.class)
.signature(ApplicationVersionSignature.obtain(context));
}
public DrawableTypeRequest<URL> load(URL url) {
return (DrawableTypeRequest<URL>) fromUrl().load(url);
}
public DrawableTypeRequest<URL> fromUrl() {
return loadGeneric(URL.class);
}

load过程分为两步操作

  • fromString():创建DrawableTypeRequest
  • load():返回当前GenericRequestBuilder

1、追踪fromString()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public DrawableTypeRequest<String> fromString() {
//第二步:调用loadGeneric方法
return loadGeneric(String.class);
}
private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
Glide.buildFileDescriptorModelLoader(modelClass, context);
if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
+ " which there is a registered ModelLoader, if you are using a custom model, you must first call"
+ " Glide#register with a ModelLoaderFactory for your custom model class");
}
return optionsApplier.apply(
//第三步:创建DrawableTypeRequest,这里追踪下去其实就是一堆参数的赋值,所以没必要再看了
new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
glide, requestTracker, lifecycle, optionsApplier));
}

2、追踪load()

load采用的是构造者模式,返回GenericRequestBuilder构造者,返回这个类可以构造出图片加载的其他属性,比如:缩略图thumbnail(0.1f)、跳过内存缓存skipMemoryCache(true)、等属性

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public DrawableRequestBuilder<ModelType> load(ModelType model) {
//追踪父类实现方式
super.load(model);
return this;
}
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
this.model = model;
isModelSet = true;
//this代表GenericRequestBuilder
return this;
}

Glide的into源码分析

一、into源码分析

into方法主要是使用多线程来加载图片,从into方法开始,按追踪步数阅读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Override
public Target<GlideDrawable> into(ImageView view) {
//第一步:调用父类into方法,追踪下去
return super.into(view);
}
public Target<TranscodeType> into(ImageView view) {
//判断当前线程,只有主线程才能继续执行
Util.assertMainThread();
if (view == null) {
throw new IllegalArgumentException("You must pass in a non null View");
}
//如果没有设置过transform()或centerCrop,那么以ImageView的scaleType属性为准
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.
}
}
//第二步:这里分为两步
//glide.buildImageViewTarget:创建由Glide自己抽象出来的Target(即泛型的View)
//into:构建请求
return into(glide.buildImageViewTarget(view, transcodeClass));
}

buildImageViewTarget其实就是将我们传进去的View,再封装成Glide抽象的泛型View,它会根据当前传入的clazz参数返回相应的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
//追踪下去
return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}
/**
* 根据当前传入的clazz参数返回相应的Target类
*/
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)");
}
}

我们回到第二步into方法,在这个方法中,主要会构建出一个Request对象,并执行这个Request对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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对象
Request previous = target.getRequest();
//如果Request存在则回收
if (previous != null) {
previous.clear();
requestTracker.removeRequest(previous);
previous.recycle();
}
//第三步:重新构建出一个Request对象
Request request = buildRequest(target);
target.setRequest(request);
lifecycle.addListener(target);
//第四步:交给Request追踪器继续执行request
requestTracker.runRequest(request);
return target;
}

我们从第三步开始看起,这里分成三种情况,但最终都会调用obtainRequest,而obtainRequest追踪下去只是对Request的初始化而已

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
private Request buildRequest(Target<TranscodeType> target) {
if (priority == null) {
priority = Priority.NORMAL;
}
//追踪下去
return buildRequestRecursive(target, null);
}
/*
* 根据不同的逻辑判断构建出不同的Request,前面的分支都是跟缩略图有关的处理
*/
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)) {
thumbnailRequestBuilder.override(overrideWidth, overrideHeight);
}
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
// Guard against infinite recursion.
isThumbnailBuilt = true;
// Recursively generate thumbnail requests.
Request thumbRequest = thumbnailRequestBuilder.buildRequestRecursive(target, coordinator);
isThumbnailBuilt = false;
coordinator.setRequests(fullRequest, thumbRequest);
return coordinator;
} else if (thumbSizeMultiplier != null) {
// Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
Request thumbnailRequest = obtainRequest(target, thumbSizeMultiplier, getThumbnailPriority(), coordinator);
coordinator.setRequests(fullRequest, thumbnailRequest);
return coordinator;
} else {
// Base case: no thumbnail.
//最终还是调用obtainRequest,追踪下去
return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
}
}
private Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
RequestCoordinator requestCoordinator) {
//追踪下去
return GenericRequest.obtain(
loadProvider,
model,
signature,
context,
priority,
target,
sizeMultiplier,
placeholderDrawable,
placeholderId,
errorPlaceholder,
errorId,
fallbackDrawable,
fallbackResource,
requestListener,
requestCoordinator,
glide.getEngine(),
transformation,
transcodeClass,
isCacheable,
animationFactory,
overrideWidth,
overrideHeight,
diskCacheStrategy);
}
public static <A, T, Z, R> GenericRequest<A, T, Z, R> obtain(
LoadProvider<A, T, Z, R> loadProvider,
A model,
Key signature,
Context context,
Priority priority,
Target<R> target,
float sizeMultiplier,
Drawable placeholderDrawable,
int placeholderResourceId,
Drawable errorDrawable,
int errorResourceId,
Drawable fallbackDrawable,
int fallbackResourceId,
RequestListener<? super A, R> requestListener,
RequestCoordinator requestCoordinator,
Engine engine,
Transformation<Z> transformation,
Class<R> transcodeClass,
boolean isMemoryCacheable,
GlideAnimationFactory<R> animationFactory,
int overrideWidth,
int overrideHeight,
DiskCacheStrategy diskCacheStrategy) {
@SuppressWarnings("unchecked")
//这里会去对应的Request池找到是否有复用的Request
GenericRequest<A, T, Z, R> request = (GenericRequest<A, T, Z, R>) REQUEST_POOL.poll();
if (request == null) {
request = new GenericRequest<A, T, Z, R>();
}
//对Request的初始化
request.init(loadProvider,
model,
signature,
context,
priority,
target,
sizeMultiplier,
placeholderDrawable,
placeholderResourceId,
errorDrawable,
errorResourceId,
fallbackDrawable,
fallbackResourceId,
requestListener,
requestCoordinator,
engine,
transformation,
transcodeClass,
isMemoryCacheable,
animationFactory,
overrideWidth,
overrideHeight,
diskCacheStrategy);
return request;
}

我们从第四步开始看起,runRequest,这里是真正执行的地方。可以看到如果没有处于暂停状态,会直接调用request.begein(),如果处于暂停状态,那么先添加到队列中,等恢复到正常状态时,会再调用request.begin()。即无论如何都会调用request.begin()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public void runRequest(Request request) {
requests.add(request);
//当前是否正在请求
if (!isPaused) {
//第五步:如果没有请求,则开始请求,追踪下去
request.begin();
} else {
//如果有请求,则添加到挂起请求中去
pendingRequests.add(request);
}
}
public void begin() {
startTime = LogTime.getLogTime();
if (model == null) {
onException(null);
return;
}
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
//第六步:如果用户设置了Override的方法,那么就会去确定图片的宽高,追踪下去
onSizeReady(overrideWidth, overrideHeight);
} else {
//如果没有设置宽高,则会去测量宽高,最终还是会走到onSizeReady方法中
target.getSize(this);
}
//先加载我们默认的图片
if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("finished run method in " + LogTime.getElapsedMillis(startTime));
}
}
@Override
public void onSizeReady(int width, int height) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;
width = Math.round(sizeMultiplier * width);
height = Math.round(sizeMultiplier * height);
//ModelLoader:负责从数据源中获取原始数据
ModelLoader<A, T> modelLoader = loadProvider.getModelLoader();
//DataFetcher:负责将图片来源转换成我们需要的图片数据
final DataFetcher<T> dataFetcher = modelLoader.getResourceFetcher(model, width, height);
if (dataFetcher == null) {
onException(new Exception("Failed to load model: \'" + model + "\'"));
return;
}
//ResourceTranscoder:负责将我们的IO流解码成Bitmap等
ResourceTranscoder<Z, R> transcoder = loadProvider.getTranscoder();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
}
loadedFromMemoryCache = true;
//第七步:通过引擎去加载,追踪下去
loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
priority, isMemoryCacheable, diskCacheStrategy, this);
loadedFromMemoryCache = resource != null;
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
}

engine其实就是个Engine类,它是负责启动负载和管理活动和缓存资源。engine.load这个方法中分为两步,第一步处理缓存,第二步真正执行加载, 构建出EngineJob,执行EngineRunnable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
Util.assertMainThread();
long startTime = LogTime.getLogTime();
final String id = fetcher.getId();
//key是用来存储缓存的唯一标识
EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
transcoder, loadProvider.getSourceEncoder());
//从内存缓存中获取图片
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
//回调
cb.onResourceReady(cached);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
//从正在使用的图片中获取图片
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
//回调
cb.onResourceReady(active);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
EngineJob current = jobs.get(key);
if (current != null) {
current.addCallback(cb);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
return new LoadStatus(cb, current);
}
EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
transcoder, diskCacheProvider, diskCacheStrategy, priority);
//如果都没有获取到缓存的图片,就会去开启线程去加载图片
EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
jobs.put(key, engineJob);
engineJob.addCallback(cb);
//第八步:线程加载的真正执行,追踪下去
engineJob.start(runnable);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Started new load", startTime, key);
}
return new LoadStatus(cb, engineJob);
}

EngineRunnable其实就是个Runnable,通过其start方法最终会调用run方法,追踪到run方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@Override
public void run() {
if (isCancelled) {
return;
}
Exception exception = null;
Resource<?> resource = null;
try {
//解码,获取我们最终的资源
resource = decode();
} catch (Exception e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Exception decoding", e);
}
exception = e;
}
if (isCancelled) {
if (resource != null) {
resource.recycle();
}
return;
}
//回调加载的结果
if (resource == null) {
onLoadFailed(exception);
} else {
//第九步:通知主线程加载图片,追踪下去
onLoadComplete(resource);
}
}
private void onLoadComplete(Resource resource) {
//追踪下去
manager.onResourceReady(resource);
}
@Override
public void onResourceReady(final Resource<?> resource) {
this.resource = resource;
//第十步:通过Handler发送消息,加载图片资源
MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
}

总结

其实Glide的源码解析还有很多东西,大概的流程如下面这张图,后面具体的分析可以看个人兴趣去阅读

这里写图片描述

坚持原创技术分享,您的支持将鼓励我继续创作!