Glide 图片框架源码分析

Glide 是 Bump Technologies 公司开源的图片加载框架,适用于 Android 平台,是谷歌推荐的图片库。
它不仅能实现平滑的图片列表滚动效果,还支持远程图片的获取、大小调整和展示,并且可以加载 Gif 动态图,功能强大。

源码基于 com.github.bumptech.glide:glide:4.12.0

简介

  1. Glide 对象是一个单例,使用 GlideBuilder 设置 BitmapPool、内存和磁盘缓存、线程池和 engine 等参数;
  2. GlideModule 全局配置。只能在主线程使用;
  3. EngineJob 提供线程切换。Transformations 剪裁与变换。TransitionOptions;
  4. 支持加载 gif 图片;
  5. 根据 ImageView 尺寸缓存图片;

优点:

  1. Google 推荐;
  2. 专注平滑的滚动;
  3. 简单易用的 API;
  4. 高性能、可扩展。

图片加载流程

Glide

基本使用:

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

Glide 初始化

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
/**
* A singleton to present a simple static interface for building requests with RequestBuilder
* and maintaining an Engine, BitmapPool, DiskCache and MemoryCache.
*/
public class Glide implements ComponentCallbacks2 {

private static volatile Glide glide;

public static Glide get(Context context) {
if (glide == null) {
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}

// 文件路径 build/generated/source/kapt/debug/com/bumptech/glide/GeneratedAppGlideModuleImpl.java
private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules(Context context) {
// 注解处理器生成的类
Class<GeneratedAppGlideModule> clazz =
(Class<GeneratedAppGlideModule>) Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
GeneratedAppGlideModule result =
clazz.getDeclaredConstructor(Context.class).newInstance(context.getApplicationContext());
return result;
}

private static void checkAndInitializeGlide(Context context, GeneratedAppGlideModule generatedAppGlideModule) {
// In the thread running initGlide(), one or more classes may call Glide.get(context).
// Without this check, those calls could trigger infinite recursion.
if (isInitializing) {
throw new IllegalStateException(
"You cannot call Glide.get() in registerComponents(),"
+ " use the provided Glide instance instead");
}
isInitializing = true;
initializeGlide(context, generatedAppGlideModule);
isInitializing = false;
}

private static void initializeGlide(Context context, GeneratedAppGlideModule generatedAppGlideModule) {
initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}

private static void initializeGlide(Context context, GlideBuilder builder, GeneratedAppGlideModule annotationGeneratedModule) {
Context applicationContext = context.getApplicationContext();
// 1. 解析 AndroidManifest.xml 中配置的 GlideModule

// 2. 设置请求工厂类
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory()
: null;
builder.setRequestManagerFactory(factory);

// 3. 设置图片参数
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}

// 4. 注册组件
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.registerComponents(applicationContext, glide, glide.registry);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}

// 5. 设置清除内存回调。onTrimMemory()
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
}
  1. 通过双重检锁的方式实现单例;

  2. 通过 AndroidManifest.xml 的配置和注解生成的类,设置参数信息;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <manifest ...>
    <!-- ... permissions -->
    <application ...>
    <meta-data
    android:name="com.mypackage.MyGlideModule"
    android:value="GlideModule" />
    <!-- ... activities and other components -->
    </application>
    </manifest>
  3. 通过 GlideBuilder 构建 Glide 对象。

绑定生命周期

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
/**
* A collection of static methods for creating new RequestManagers or
* retrieving existing ones from activities and fragment.
*/
public class RequestManagerRetriever {
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) {
return get((Activity) context);
} else if (context instanceof ContextWrapper
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}

public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, null, isActivityVisible(activity));
}
}

private RequestManager getApplicationManager(Context context) {
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
applicationManager = factory.build(glide, new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(), context.getApplicationContext());
}
}
}

return applicationManager;
}

private RequestManager supportFragmentGet(Context context, FragmentManager fm,
Fragment parentHint, boolean isParentVisible) {
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}

private SupportRequestManagerFragment getSupportRequestManagerFragment(final FragmentManager fm, Fragment parentHint) {
SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}

private static final RequestManagerFactory DEFAULT_FACTORY =
new RequestManagerFactory() {
@Override
public RequestManager build(lide glide,
Lifecycle lifecycle, ...) {
return new RequestManager(glide, lifecycle, ...);
}
};
}
  1. Context 不能为 null;
  2. 非 UI 线程或 Application 上下文绑定的是全局生命周期;
  3. UI 线程,将 SupportRequestManagerFragment 实例添加到当前 Activity 中,实现对 Activity 生命周期的监听;

绑定资源加载类型

RequestManager 用于管理和发起请求,而且能感知组件的生命周期。基于 Lifecycle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* A class for managing and starting requests for Glide.
*/
public class RequestManager{
public RequestBuilder<Drawable> load(String string) {
return asDrawable().load(string);
}

public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}

public RequestBuilder<File> asFile() {
return as(File.class).apply(skipMemoryCacheOf(true));
}

public RequestBuilder<Bitmap> asBitmap() {
return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
}

public <ResourceType> RequestBuilder<ResourceType> as(Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
}
  1. 绑定资源类型,如 URL,Drawable, File, Bitmap 等。

实例化 ImageViewTarget,绑定 ImageView

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
public class RequestBuilder<TranscodeType>{
public RequestBuilder<TranscodeType> load(String string) {
return loadGeneric(string);
}

private RequestBuilder<TranscodeType> loadGeneric(Object model) {
if (isAutoCloneEnabled()) {
return clone().loadGeneric(model);
}
this.model = model;
isModelSet = true;
return selfOrThrowIfLocked();
}

public ViewTarget<ImageView, TranscodeType> into(ImageView view) {
Util.assertMainThread();
BaseRequestOptions<?> requestOptions = this;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
switch (view.getScaleType()) {
case CENTER_CROP:
requestOptions = requestOptions.clone().optionalCenterCrop();
break;
case CENTER_INSIDE:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
requestOptions = requestOptions.clone().optionalFitCenter();
break;
case FIT_XY:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case CENTER:
case MATRIX:
default:
// Do nothing.
}
}

return into(glideContext.buildImageViewTarget(view, transcodeClass),
null, requestOptions, Executors.mainThreadExecutor());
}

private <Y extends Target<TranscodeType>> Y into(Y target, RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options, Executor callbackExecutor) {

// 构造 SingleRequest 对象
Request request = buildRequest(target, targetListener, options, callbackExecutor);
Request previous = target.getRequest();
// 检查是否可以复用前一个 Request;
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}

requestManager.clear(target);
// 通过 setTag() 绑定 ImageView 的 Request
target.setRequest(request);
// 添加到请求队列
requestManager.track(target, request);

return target;
}
}

public class ImageViewTargetFactory {
public <Z> ViewTarget<ImageView, Z> buildTarget(mageView view, Class<Z> clazz) {
if (Bitmap.class.equals(clazz)) {
return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException(
"Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
}
}
}
  1. into(imageView) 必须在主线程调用;
  2. 设置裁剪模式;
  3. 通过 GlideContext 创建 ViewTarget。只支持 BitmapImageViewTarget 和 BitmapImageViewTarget;
    1. 构造 SingleRequest,并通过 ImageView#setTag() 绑定;
  4. 通过 RequestManager#track(target, 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
public class RequestManager {
synchronized void track(Target<?> target, Request request) {
// 添加到 ImageViewTarget 集合
targetTracker.track(target);
// 发起图片请求
requestTracker.runRequest(request);
}
}

/**
* A class for tracking, canceling, and restarting in progress, completed, and failed requests.
*/
public class RequestTracker {

public void runRequest(Request request) {
// 添加请求到请求集合
requests.add(request);
// 如果请求没有暂停就发起请求
if (!isPaused) {
request.begin();
} else {
// 清除请求,并且添加到待调度集合
request.clear();
pendingRequests.add(request);
}
}
}

/**
* A Request that loads a Resource into a given Target.
*/
public final class SingleRequest<R>{
public void begin() {
synchronized (requestLock) {
if (model == null) {
onLoadFailed(new GlideException("Received null model"), logLevel);
return;
}

if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}

if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE, false);
return;
}

status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
// 获取 View 的测量宽高,并回调 onSizeReady() 方法
target.getSize(this);
}

if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
// 回调 BitmapImageViewTarget#setResource() -> ImageView.setImageDrawable()
target.onLoadStarted(getPlaceholderDrawable());
}
}
}

public void onSizeReady(int width, int height) {
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;

float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);

loadStatus = engine.load(glideContext, model,... callbackExecutor);
}
}
  1. 根据请求状态执行不同操作;
  2. 宽高确定后回调 onSizeReady() ,通过 Engine 请求图片。
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
/** Responsible for starting loads and managing active and cached resources. */
public class Engine{

public <R> LoadStatus load(...){
EngineKey key = keyFactory.buildKey();
EngineResource<?> memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
if (memoryResource == null) {
return waitForExistingOrStartNewJob(...);
}
cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE, false);
return null;
}

private EngineResource<?> loadFromMemory(
EngineKey key, boolean isMemoryCacheable, long startTime) {
if (!isMemoryCacheable) {
return null;
}

EngineResource<?> active = loadFromActiveResources(key);
if (active != null) {
return active;
}

EngineResource<?> cached = loadFromCache(key);
if (cached != null) {
return cached;
}

return null;
}
}

  1. 构造请求的唯一标识;
  2. 内存缓存存在,调用 onResourceReady() 回调;
  3. 否则网络加载资源;

缓存类型:

  • 活动资源 (Active Resources):正在显示的资源
  • 内存缓存 (Memory cache):显示过的资源
  • 资源类型(Resource):被解码、转换后的资源
  • 数据来源 (Data):源文件(未处理过)资源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Engine.java
private <R> LoadStatus waitForExistingOrStartNewJob(...){
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
current.addCallback(cb, callbackExecutor);
return new LoadStatus(cb, current);
}
EngineJob<R> engineJob = engineJobFactory.build(key, ...);
DecodeJob<R> decodeJob = decodeJobFactory.build(engineJob, ...);
jobs.put(key, engineJob);

engineJob.addCallback(cb, callbackExecutor);
engineJob.start(decodeJob);
return new LoadStatus(cb, engineJob);
}
  1. 如果请求已存在,设置回调返回;
  2. 否则,构造 EngineJob 和 DecodeJob,加入到 EngineJob 集合中;
  3. 新加入的 EngineJob 设置回调,启动 EngineJob。
1
2
3
4
5
6
7
8
9
10
11
12
13
// EngineJob.java
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor =
decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
executor.execute(decodeJob);
}

private GlideExecutor getActiveSourceExecutor() {
return useUnlimitedSourceGeneratorPool
? sourceUnlimitedExecutor
: (useAnimationPool ? animationExecutor : sourceExecutor);
}
  1. 根据缓存策略决定使用哪个线程池。默认情况返回 diskCacheExecutor。 共三种线程池:diskCacheExecutor, sourceUnlimitedExecutor, animationExecutor 或 sourceExecutor 执行请求。

Glide 默认通过 GlideExecutor.newSourceExecutor() 为 sourceExecutor 初始化。

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
/** A prioritized ThreadPoolExecutors for running jobs in Glide. */
public final class GlideExecutor implements ExecutorService {
public static GlideExecutor newSourceExecutor() {
return newSourceBuilder().build();
}

public static GlideExecutor.Builder newSourceBuilder() {
return new GlideExecutor.Builder(false)
.setThreadCount(calculateBestThreadCount())
.setName(DEFAULT_SOURCE_EXECUTOR_NAME);
}

public GlideExecutor build() {
ThreadPoolExecutor executor =
new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
/*keepAliveTime=*/ threadTimeoutMillis,
TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(),
new DefaultThreadFactory(name, uncaughtThrowableStrategy, preventNetworkOperations));

if (threadTimeoutMillis != NO_THREAD_TIMEOUT) {
executor.allowCoreThreadTimeOut(true);
}

return new GlideExecutor(executor);
}
}
  1. 设置 GlideExecutor 线程池;
  2. 线程池调度执行 DecodeJob;
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
/**
* A class responsible for decoding resources either from cached data or from the original source
* and applying transformations and transcodes.
*/
class DecodeJob<R> implements Runnable,... {
@Override
public void run() {
if (isCancelled) {
notifyFailed();
return;
}
runWrapped();
}

private void runWrapped() {
switch (runReason) {
case INITIALIZE:
stage = getNextStage(Stage.INITIALIZE);
currentGenerator = getNextGenerator();
runGenerators();
break;
case SWITCH_TO_SOURCE_SERVICE:
runGenerators();
break;
case DECODE_DATA:
decodeFromRetrievedData();
break;
default:
throw new IllegalStateException("Unrecognized run reason: " + runReason);
}
}

private Stage getNextStage(Stage current) {
switch (current) {
case INITIALIZE:
return diskCacheStrategy.decodeCachedResource()
? Stage.RESOURCE_CACHE
: getNextStage(Stage.RESOURCE_CACHE);
case RESOURCE_CACHE:
return diskCacheStrategy.decodeCachedData()
? Stage.DATA_CACHE
: getNextStage(Stage.DATA_CACHE);
case DATA_CACHE:
// Skip loading from source if the user opted to only retrieve the resource from cache.
return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
case SOURCE:
case FINISHED:
return Stage.FINISHED;
default:
throw new IllegalArgumentException("Unrecognized stage: " + current);
}
}

private void runGenerators() {
currentThread = Thread.currentThread();
boolean isStarted = false;
while (!isCancelled
&& currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
stage = getNextStage(stage);
currentGenerator = getNextGenerator();

// 如果任务是加载资源阶段,则切换任务执行环境
if (stage == Stage.SOURCE) {
reschedule();
return;
}
}
if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
notifyFailed();
}
}

/** Where we're trying to decode data from. */
private enum Stage {
/** The initial stage. */
INITIALIZE,
/** Decode from a cached resource. */
RESOURCE_CACHE,
/** Decode from cached source data. */
DATA_CACHE,
/** Decode from retrieved source. */
SOURCE,
/** Encoding transformed resources after a successful load. */
ENCODE,
/** No more viable stages. */
FINISHED,
}
}
  1. 判断当前任务在 INITIALIZE, RESOURCE_CACHE, DATA_CACHE, SOURCE 或 FINISHED 的哪个阶段;
  2. 根据不同的 Stage 执行不同的任务。
    • ResourceCacheGenerator 从转换后的缓存中读取资源;
    • DataCacheGenerator 从原始的缓存中读取资源;
    • SourceGenerator 从源文件加载资源。
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
/**
* Generates DataFetchers from original source data
* using registered ModelLoaders and the model provided for the load.
*/
class SourceGenerator {
public boolean startNext() {
if (dataToCache != null) {
Object data = dataToCache;
dataToCache = null;
cacheData(data);
}

if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
return true;
}
sourceCacheGenerator = null;

loadData = null;
boolean started = false;
while (!started && hasNextModelLoader()) {
loadData = helper.getLoadData().get(loadDataListIndex++);
if (loadData != null
&& (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
|| helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
started = true;
startNextLoad(loadData);
}
}
return started;
}

private void startNextLoad(final LoadData<?> toStart) {
loadData.fetcher.loadData(helper.getPriority(),
new DataCallback<Object>() {
@Override
public void onDataReady(Object data) {
if (isCurrentRequest(toStart)) {
onDataReadyInternal(toStart, data);
}
}

@Override
public void onLoadFailed(Exception e) {
if (isCurrentRequest(toStart)) {
onLoadFailedInternal(toStart, e);
}
}
});
}
}
  1. 通过 HttpUrlFetcher 等 Fetcher 加载图片。

MultiModelLoader.MultiFetcher -> OkHttpStreamFetcher(需要引入 okhttp3-integration)

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

/** A DataFetcher that retrieves an InputStream for a Url. */
public class HttpUrlFetcher{

public void loadData( Priority priority, DataCallback<? super InputStream> callback) {
InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
callback.onDataReady(result);
}

private InputStream loadDataWithRedirects(URL url, ...){
// ... 最多重定向 5 次
urlConnection = buildAndConfigureConnection(url, headers);
urlConnection.connect();
stream = urlConnection.getInputStream();

if (isCancelled) {
return null;
}

final int statusCode = getHttpStatusCodeOrInvalid(urlConnection);
if (isHttpOk(statusCode)) {
return getStreamForSuccessfulRequest(urlConnection);
} else if (isHttpRedirect(statusCode)) {
URl redirectUrl = new URL(url, redirectUrlString);
cleanup();
return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
} else {
// 抛出 HttpException 异常
}
}
}

  1. 通过 HttpURLConnection 获取图片 Stream;
  2. 回调 DataCallback#onDataFetcherReady() -> SourceGenerator#onDataReadyInternal() -> DecodeJob#onDataFetcherReady()。
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
// DecodeJob.java
public void onDataFetcherReady(...) {
if (Thread.currentThread() != currentThread) {
runReason = RunReason.DECODE_DATA;
callback.reschedule(this);
} else {
decodeFromRetrievedData();
}
}

private void decodeFromRetrievedData() {
Resource<R> resource = decodeFromData(currentFetcher, currentData, currentDataSource);
if (resource != null) {
notifyEncodeAndRelease(resource, currentDataSource, isLoadingFromAlternateCacheKey);
} else {
runGenerators();
}
}

private void notifyEncodeAndRelease(){
notifyComplete(result, ...);
stage = Stage.ENCODE;
}

private void notifyComplete(Resource<R> resource, ...) {
callback.onResourceReady(resource, dataSource, isLoadedFromAlternateCacheKey);
}

回调 ImageViewTarget,显示图片

1
2
3
4
5
6
7
8
// SingleRequest.java
private void onResourceReady(Resource<R> resource...){
status = Status.COMPLETE;
if (!anyListenerHandledUpdatingTarget) {
Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
target.onResourceReady(result, animation);
}
}

SingleRequest#onResourceReady() 方法最终会调用到 BitmapImageViewTarget.setResource() 方法。

1
2
3
4
5
6
7
8
9
/**
* A Target that can display an Bitmap in an ImageView.
*/
public class BitmapImageViewTarget extends ImageViewTarget<Drawable> {
@Override
protected void setResource(Drawable resource) {
view.setImageBitmap(resource);
}
}

GlideAnnotationProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// https://github.com/bumptech/glide/blob/master/annotation/compiler/src/main/java/com/bumptech/glide/annotation/compiler/GlideAnnotationProcessor.java
public final class GlideAnnotationProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
processorUtil = new ProcessorUtil(processingEnvironment);
IndexerGenerator indexerGenerator = new IndexerGenerator(processorUtil);
libraryModuleProcessor = new LibraryModuleProcessor(processorUtil, indexerGenerator);
appModuleProcessor = new AppModuleProcessor(processingEnvironment, processorUtil);
extensionProcessor = new ExtensionProcessor(processingEnvironment, processorUtil, indexerGenerator);
}

@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> result = new HashSet<>();
// GlideModule 注解
result.addAll(libraryModuleProcessor.getSupportedAnnotationTypes());
// GlideExtension 注解
result.addAll(extensionProcessor.getSupportedAnnotationTypes());
return result;
}
}

总结

  1. 通过向 Activity 添加无界面的 RequestManagerFragment 绑定生命周期;
  2. 将 ImageView 包装成 ImageViewTarget;
  3. 执行新的请求前,会清除这个 ImageViewTarget 之前绑定的请求,绑定新的请求;
  4. 默认使用 HttpUrlConnection 作为网络请求模块;
  5. 获取图片资源成功则会调用 ImageViewTarget#onResourceReady() 方法,否则调用 onLoadFailed() 方法。都会调用 ImageView.setImageBitmap(resource) 设置图片;

流程图

Glide 加载流程

参考

[1] Glide - github
[2] Glide Docs-Cn
[3] glide-transformations
[4] 深入理解 Glide
[5] Glide 分析文章