上一篇讲了Glide源码分析之Glide和RequestManager构建过程,有兴趣能够去看一下,这篇我从头至尾又从新讲解Glide从构建到请求网络资源的整个过程,先看一下图,这张图是看源码记录的,不可能所有流程都记下来,这张图只是把整个流程涉及到的比较重要的方法给画出来。java
####Glide优点: 一、可配置度高,自适应度高; 二、支持多种数据源,本地、网络、assets、gif; 三、高效缓存,支持memory和diskp图片缓存,默认二级缓存; 四、使用BitmapPool高效处理Bitmap,避免频繁GC; 五、图片加载过程能够监听,咱们项目中使用了OkHttp做为Glide的网络层监听下载图片进度; 六、生命周期,Glide绑定Activity的生命周期;缓存
从图中看可能要分几个模块讲,按照图中的步骤分类讲解,分为:一、二、三、四、五、六、七、八、9,尽可能详细,固然因为篇幅的缘由,仅仅讲解Glide请求网络的过程,像缓存、编解码这些基本是不会讲解,不事后面会分模块功能讲解。网络
####一、Glide的初始化app
Glide.with:ide
public static RequestManager with(FragmentActivity activity) {
//第一步是构建RequestManagerRetriever和建立Glide,以后调用getRetriever方法
RequestManagerRetriever requestManagerRetriever = getRetriever(activity);
RequestManager requestManager = requestManagerRetriever.get(activity);
return requestManager;
}
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
return Glide.get(context).getRequestManagerRetriever();
}
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
复制代码
能够看到在with方法中又调用getRetriever方法以后又调用get方法,其实真正作建立和初始化的操做在initializeGlide方法中源码分析
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
//Application
Context applicationContext = context.getApplicationContext();
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
//是否是在Manifest注册了,在4.0以前就是使用了Manifest自定Module
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
//4.0以后使用了注解的方式,可是Manifest尚未废弃
if (annotationGeneratedModule != null && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
while (iterator.hasNext()) {
com.bumptech.glide.module.GlideModule current = iterator.next();
if (!excludedModuleClasses.contains(current.getClass())) {
continue;
}
}
iterator.remove();
}
}
//获取RequestManager工程
RequestManagerRetriever.RequestManagerFactory factory = annotationGeneratedModule != null ? annotationGeneratedModule.getRequestManagerFactory() : null;
//将RequestManager工厂注入Builder
builder.setRequestManagerFactory(factory);
// 自定义Module,可更改Glide配置
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
// 自定义Module,可更改Glide配置
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
//经过Builder建立Glide
Glide glide = builder.build(applicationContext);
//manifest注册组件
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
try {
module.registerComponents(applicationContext, glide, glide.registry);
} catch (AbstractMethodError e) {
}
}
// 注解生成并注册组件
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
// 内存监控
applicationContext.registerComponentCallbacks(glide);
//最后赋值
Glide.glide = glide;
}
复制代码
在initializeGlide方法中主要有几点:fetch
根据注解获取各类组件和自定义模块之类的东西动画
annotationGeneratedModule.applyOptions(applicationContext, builder);
//经过Builder建立Glide,注意这里为何要把这段代码写在注册组件和自定义模块之间
Glide glide = builder.build(applicationContext);
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
复制代码
最后将RequestManagerFactory注入GlideBiulder中:ui
//获取RequestManager工程
RequestManagerRetriever.RequestManagerFactory factory = annotationGeneratedModule != null ? annotationGeneratedModule.getRequestManagerFactory() : null;
//将RequestManager工厂注入Builder
builder.setRequestManagerFactory(factory);
复制代码
加下来分析一下: Glide glide = builder.build(applicationContext);this
Glide build(@NonNull Context context) {
//通常都所有判断是否为null,因此咱们在自定义Module时,重写applyOptions方法,可更改配置不使用默认的配置
if (sourceExecutor == null) {
sourceExecutor = GlideExecutor.newSourceExecutor();
}
//硬盘缓存线程池
if (diskCacheExecutor == null) {
diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
}
// 动画线程池
if (animationExecutor == null) {
animationExecutor = GlideExecutor.newAnimationExecutor();
}
//内存缓存大小计算
if (memorySizeCalculator == null) {
memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
}
//网络监视器工程
if (connectivityMonitorFactory == null) {
connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
}
//Bitmap复用池(享元)
if (bitmapPool == null) {
int size = memorySizeCalculator.getBitmapPoolSize();
if (size > 0) {
bitmapPool = new LruBitmapPool(size);
} else {
bitmapPool = new BitmapPoolAdapter();
}
}
if (arrayPool == null) {
arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
}
//内存缓存
if (memoryCache == null) {
memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
}
//磁盘缓存工厂
if (diskCacheFactory == null) {
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}
if (engine == null) {
engine = new Engine(
memoryCache,
diskCacheFactory,
diskCacheExecutor,
sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor(),
animationExecutor,
isActiveResourceRetentionAllowed);
}
//请求观察者,成功或失败
if (defaultRequestListeners == null) {
defaultRequestListeners = Collections.emptyList();
} else {
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
}
// 在Glide.java文件中 builder.setRequestManagerFactory(factory)
// requestManagerRetriever主要是检查RequestManager
RequestManagerRetriever requestManagerRetriever = new RequestManagerRetriever(requestManagerFactory);
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptions.lock(),
defaultTransitionOptions,
defaultRequestListeners,
isLoggingRequestOriginsEnabled);
}
复制代码
这段代码不少,不过逻辑是通简单的;无非就是各类线程池的构建和RequestManagerRetriever的建立还有Engine的建立这个比较重要,管理者整个Glide的资源的工做都是Engine作的。
####二、建立RequestManager和生命周期的关联
RequestManager requestManager = requestManagerRetriever.get(activity);
在with方法中调用了requestManagerRetriever.get(activity)方法,进去瞄一眼:
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
复制代码
实际上get方法有不少重载的方法,其实逻辑是同样的,暂时无论,先看看supportFragmentGet方法:
private RequestManager supportFragmentGet(@NonNull Context context, @NonNull FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
//1 获取Fragment
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
//尝试在Fragment中获取RequestManager
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {//不存在
Glide glide = Glide.get(context);
//建立RequestManager
requestManager = factory.build(glide,
current.getGlideLifecycle(),//生命周期的回调
current.getRequestManagerTreeNode(), context);
//并保存到Fragment中
current.setRequestManager(requestManager);
}
return requestManager;
}
复制代码
看到1了吗:
private SupportRequestManagerFragment getSupportRequestManagerFragment(@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
//检索是否存在SupportRequestManagerFragment,若是不存在则建立一个Fragmment并添加到缓存中
SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {//不存在
//尝试从缓存中读取
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {//仍是不存在
//那么就建立一个新的Fragment
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
//添加到缓存中
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//绑定成功后则从pendingRequestManagerFragments移除fragment。这里的pendingRequestManagerFragments主要是防止fragment重复建立,由于每一个activity必须对应一个惟一的fragment。
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
复制代码
检索是否存在SupportRequestManagerFragment,若是不存在则建立一个Fragmment并添加到缓存中, 由于Glide使用一个隐藏的Fargment做为监听声明周期做用,至于为何添加Fragment又移除,我在谷歌查了一下说是这里的pendingRequestManagerFragments主要是防止fragment重复建立,由于每一个activity必须对应一个惟一的fragment。
通过上面的步骤基本上就是Glide建立和初始化,并建立了RequestManager,并将RequestManager保存至Fragment中,以及关联生命周期。
####三、接下来就是使用load()和into()方法:
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
@NonNull
@CheckResult
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
复制代码
实际上load方法主要是构建RequestBuilder,接着没什么好说的,看一下into
private <Y extends Target<TranscodeType>> Y into(@NonNull Y target, @Nullable RequestListener<TranscodeType> targetListener, BaseRequestOptions<?> options, Executor callbackExecutor) {
Preconditions.checkNotNull(target);
/**
* 若是不先调用load就抛这个异常
*/
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
//构建请求会返回一个SingleRequest
Request request = buildRequest(target, targetListener, options, callbackExecutor);
Request previous = target.getRequest();
//上一个请求的处理,就是上一个请求因为某种缘由暂停请求
if (request.isEquivalentTo(previous) && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
requestManager.clear(target);
target.setRequest(request);//target绑定一个请求
// 真正开始请求的地方
requestManager.track(target, request);
return target;
}
复制代码
其实这段代码看注释应该就能明白大致是作什么的,主要是若是请求暂停,就开始请求,比较重要的是requestManager.track(target, request)这段代码是要开始新请求,Glide加载图片的整个触发点。
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
复制代码
走了那么久,终于看到runRequest(),运行请求?那就看一下。
/**
* 开始追踪请求
* <p>
* Starts tracking the given request.
*/
public void runRequest(@NonNull Request request) {
requests.add(request);
if (!isPaused) {
//若是暂停就开始请求
request.begin();
} else {
request.clear();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Paused, delaying request");
}
//待处理的请求
pendingRequests.add(request);
}
}
复制代码
仍是没看到什么东西, 那就看一下request.begin(),实际上应该看SingleRequest的begin方法。
@Override
public synchronized void begin() {
if (model == null) {
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
width = overrideWidth;
height = overrideHeight;
}
onLoadFailed(new GlideException("Received null model"), logLevel);
return;
}
if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}
//回调target,资源请求已经完成,好比内存缓存,这些不须要再请求网络的
if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
/**
*
*从新启动既没有完成也还没不运行的请求,这些能够被视为新的请求,而且能够从头开始从新运行。
*/
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
//这里面真的是要请求网络了
onSizeReady(overrideWidth, overrideHeight);
} else {
target.getSize(this);
}
/**
* 回调给target通知请求已经开始
*
*/
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE) && canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
}
复制代码
直接看我代码的注释吧,其实reSizeReady根据计算大小,而后开始加载图片。
@Override
public synchronized 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,
requestOptions.getSignature(),
this.width,
this.height,
requestOptions.getResourceClass(),
transcodeClass,
priority,
requestOptions.getDiskCacheStrategy(),
requestOptions.getTransformations(),
requestOptions.isTransformationRequired(),
requestOptions.isScaleOnlyOrNoTransform(),
requestOptions.getOptions(),
requestOptions.isMemoryCacheable(),
requestOptions.getUseUnlimitedSourceGeneratorsPool(),
requestOptions.getUseAnimationPool(),
requestOptions.getOnlyRetrieveFromCache(),
this,
callbackExecutor);
if (status != Status.RUNNING) {
loadStatus = null;
}
}
复制代码
就是计算大小,而后开始加载图片,看一下engine.load()方法吧。
public synchronized <R> LoadStatus load(
GlideContext glideContext,
Object model,
Key signature,
int width,
int height,
Class<?> resourceClass,
Class<R> transcodeClass,
Priority priority,
DiskCacheStrategy diskCacheStrategy,
Map<Class<?>, Transformation<?>> transformations,
boolean isTransformationRequired,
boolean isScaleOnlyOrNoTransform,
Options options,
boolean isMemoryCacheable,
boolean useUnlimitedSourceExecutorPool,
boolean useAnimationPool,
boolean onlyRetrieveFromCache,
ResourceCallback cb,
Executor callbackExecutor) {
long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;
// -------------开始检测缓存----------------
EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations, resourceClass, transcodeClass, options);
// 第一级内存缓存
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
// 若是内存中有,就当即返回
cb.onResourceReady(active, DataSource.MEMORY_CACHE);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
// 第二级内存缓存
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
current.addCallback(cb, callbackExecutor);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
return new LoadStatus(cb, current);
}
EngineJob<R> engineJob = engineJobFactory.build(key,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache);
DecodeJob<R> decodeJob = decodeJobFactory.build(glideContext,
model,
key,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
onlyRetrieveFromCache,
options,
engineJob);
jobs.put(key, engineJob);
engineJob.addCallback(cb, callbackExecutor);
// 开始执行任务
engineJob.start(decodeJob);
return new LoadStatus(cb, engineJob);
}
复制代码
看代码代码注释,应该差很少,主要是 engineJob.start(decodeJob)启动线程执行任务。
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
executor.execute(decodeJob);
复制代码
}
既然是线程,那必然decodeJob必定是Runnable,直奔DecodeJob的run方法,看看究竟干啥。
@Override
public void run() {
//执行网络
DataFetcher<?> localFetcher = currentFetcher;
try {
if (isCancelled) {
notifyFailed();
return;
}
runWrapped();
} catch (CallbackException e) {
throw e;
} catch (Throwable t) {
if (stage != Stage.ENCODE) {
throwables.add(t);
notifyFailed();
}
if (!isCancelled) {
throw t;
}
throw t;
} finally {
/**
* 咱们自定组件时回调cleanup(),如OkHttpStreamFetcher中
*
*/
if (localFetcher != null) {
localFetcher.cleanup();
}
}
}
复制代码
没看到执行什么操做?看一下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);
}
}
复制代码
这个方法就至关重要了,其实就是根据当前的状态,生成加载图片资源的代Generator,不信?那就看一下getNextGenerator方法。
private DataFetcherGenerator getNextGenerator() {
switch (stage) {
case RESOURCE_CACHE:
return new ResourceCacheGenerator(decodeHelper, this);//须要解码被转换以后的缓存
case DATA_CACHE:
return new DataCacheGenerator(decodeHelper, this);//须要解码原图缓存
case SOURCE:
return new SourceGenerator(decodeHelper, this);//原始数据代,须要加载网络数据
case FINISHED:
return null;
default:
throw new IllegalStateException("Unrecognized stage: " + stage);
}
}
复制代码
无论你信不信,反正我是信了,那建立这些加载图片资源干啥?回到刚才的runWrapper方法,尽然还有runGenerators方法,看一波。
private void runGenerators() {
boolean isStarted = false;
/**
*
* 若是getNextGenerator()返回SourceGenerator类,那么须要请求网络了
* 开始网络请求图片
*/
while (!isCancelled && currentGenerator != null && !(isStarted = currentGenerator.startNext())) {
stage = getNextStage(stage);
currentGenerator = getNextGenerator();
if (stage == Stage.SOURCE) {
//从新调度startNext()
reschedule();
return;
}
}
if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
notifyFailed();
}
}
复制代码
代码很少,看一下currentGenerator.startNext(),这个方法是启动图片加载代Generator的,是个接口,那咱们选SourceGenerator这个吧。
/**
* 准备开始拉取网络数据
*
* @return
*/
@Override
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;
/**
* DataFetcher的loadData()方法的回调时机,请看实现类{@link HttpUrlFetcher}
*
* 还把回调传进去
*/
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
return started;
}
复制代码
DataFetcherGenerator有三个子类分别作不一样的事情,
SourceGenerator: 使用已注册的ModelLoaders和为加载提供的model,从原始源数据生成DataFetcher DataFetchers。 根据磁盘缓存策略,源数据可能首先写入磁盘,而后从缓存文件加载而不是直接返回。
ResourceCacheGenerator 从已转换的资源数据的缓存文件中采样数据生成DataFetchers。
DataCacheGenerator 从原始未修改源数据的缓存文件采样数据生成DataFetchers。
选SourceGenetator分析:
loadData.fetcher.loadData(helper.getPriority(), this);
复制代码
使用已注册的ModelLoaders和load提供的model,从原始源数据生成DataFetchers。 根据磁盘缓存策略,源数据可能首先写入磁盘,而后从缓存文件加载而不是直接返回。
private volatile ModelLoader.LoadData<?> loadData;
class LoadData<Data> {
public final Key sourceKey;
public final List<Key> alternateKeys;
public final DataFetcher<Data> fetcher;
public LoadData(@NonNull Key sourceKey, @NonNull DataFetcher<Data> fetcher) {
this(sourceKey, Collections.<Key>emptyList(), fetcher);
}
public LoadData(@NonNull Key sourceKey, @NonNull List<Key> alternateKeys,
@NonNull DataFetcher<Data> fetcher) {
this.sourceKey = Preconditions.checkNotNull(sourceKey);
this.alternateKeys = Preconditions.checkNotNull(alternateKeys);
this.fetcher = Preconditions.checkNotNull(fetcher);
}
}
复制代码
其实是若是咱们自定义模块,那么会从DataFetcher和ModelLoader中去作网络请求。自此文章结束。