Glide基本用法
Glide.with(context).load(obj).into(imageView)
with()源码解析
public static RequestManager with(Context context) {
return getRetriever(context).get(context);
}
public static RequestManager with(Activity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(View view) {
return getRetriever(view.getContext()).get(view);
}
- 会根据上面传入的参数不一样,然后调用
getRetriever(),Glide.get(Context)主要是检查并初始化单例对象Glide,并且判断AndroidManifest有没有配置module或者自己新建一个类添加注解GlideModule,如果有会反射获取会注册Glide中的组件和参数完成后,调用getRequestManagerRetriever()返回一个RequestManagerRetriever对象
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
return Glide.get(context).getRequestManagerRetriever();
}
- 返回的
RequestManagerRetriever对象又调用了get(T t)方法,这也是一个重载函数,共同特点就是如果是非主线程调用Glide统一当做Application来处理,分类看一下
Context对象会根据Context对应的实例调用不同的方法。
其他方法共同点都是创建一个隐藏的Fragment
如果实参是V4包中Activity或Fragment会创建SupportRequestManagerFragment对象
如果实参不是V4包中的就返回RequestManagerFragment对象
RequestManager和Fragment进行一个生命周期的绑定,如果当页面被隐藏,图片加载请求也会相应取消,从而更加节约性能。
最终返回的是一个RequestManager对象。
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) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, null /*parentHint*/);
}
}
public RequestManager get(Fragment fragment) {
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm, fragment);
}
}
public RequestManager get(Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, null /*parentHint*/);
}
}
public RequestManager get(View view) {
if (Util.isOnBackgroundThread()) {
return get(view.getContext().getApplicationContext());
}
Activity activity = findActivity(view.getContext());
// The view might be somewhere else, like a service.
if (activity == null) {
return get(view.getContext().getApplicationContext());
}
// Support Fragments.
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
- 综上分析,
with()就返回一个RequestManager对象,然后根据传入的参数来绑定图片加载的生命周期。
Glide如何绑定生命周期
- 下面来看看创建的
Fragment是如何和RequestManager进行生命周期绑定,由上分析可知我们会得到一个Fragment对象,在Fragment构造函数中会创建一个ActivityFragmentLifecycle,可以看到在各个生命周期函数都会调用lifecycle的函数进行监听。
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@Override
public void onDetach() {
super.onDetach();
parentFragmentHint = null;
unregisterFragmentWithRoot();
}
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
- 再来看看
RequestManger的创建过程,current参数就是上面创建好的Fragment对象,通过getGlideLifecycle方法获取到刚才在构造函数中创造的ActivityFragmentLifecycle的对象,从而传递给通过工厂模式建立的RequestManager。
private RequestManager supportFragmentGet(Context context, FragmentManager fm,
Fragment parentHint) {
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());
current.setRequestManager(requestManager);
}
return requestManager;
}
-
RequestManager自己实现了LifecycleListener的监听器接口,在构造函数中,在从上面Fragment传递过来的ActivityFragmentLifecycle对象添加监听器。在onStart()中启动请求,在onStop()中暂停请求,在onDestroy()做一些清理工作。
public class RequestManager implements LifecycleListener {
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory) {
......
connectivityMonitor =
factory.build(context, new RequestManagerConnectivityListener(requestTracker));
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
}
......
@Override
public void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public void onStop() {
pauseRequests();
targetTracker.onStop();
}
@Override
public void onDestroy() {
targetTracker.onDestroy();
for (Target<?> target : targetTracker.getAll()) {
clear(target);
}
targetTracker.clear();
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
mainHandler.removeCallbacks(addSelfToLifecycle);
glide.unregisterRequestManager(this);
}
}
- 监听器也注册了,那么进入
ActivityFragmentLifecycle内部看看,发现在内部的生命周期方法中会调用监听器对应的方法。
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
- 经过上面的分析发现整个过程就理顺了,先创建一个
Fragment对象并在构造函数中创建Lifecycle对象
,在通过工厂模式创建RequestManager的时候会把Lifecycle对象传递进去。
RequestManger则会在构造函数处会将接受的Lifecycle添加监听器,RequestManager自身实现了LifecycleListener并在实现的接口方法中根据生命周期方法来启动和暂停请求。
Lifecycle对象在添加监听器后,会在生命周期方法中回调监听器对应的方法。
因此当Fragment会在生命周期方法中调用Lifecycle对应的生命周期方法,最终也就是在调用RequestManger中的生命周期方法,因此实现了请求和生命周期的绑定,从而可以根据生命周期来启动和暂停请求。
load()源码解析
- 通过
with()返回RequestManager对象再调用load()方法,如果没有调用asxxx()方法,都默认调用asDrawable()方法,最后创建返回了一个RequestBuilder<Drawable>对象。
public RequestBuilder<Drawable> load(@Nullable Object model) {
return asDrawable().load(model);
}
- 在
RequestBuilder对象中,根据参数的不同,load()也有很多方法的重载,如下所示,发现共同点所有方法都会调用loadGeneric(T t)方法,下面来看看这个方法的实现。
public RequestBuilder<TranscodeType> load(@Nullable Object model) {
return loadGeneric(model);
}
public RequestBuilder<TranscodeType> load(@Nullable String string) {
return loadGeneric(string);
}
public RequestBuilder<TranscodeType> load(@Nullable Uri uri) {
return loadGeneric(uri);
}
public RequestBuilder<TranscodeType> load(@Nullable File file) {
return loadGeneric(file);
}
public RequestBuilder<TranscodeType> load(@Nullable Integer resourceId) {
return loadGeneric(resourceId).apply(signatureOf(ApplicationVersionSignature.obtain(context)));
}
public RequestBuilder<TranscodeType> load(@Nullable URL url) {
return loadGeneric(url);
}
public RequestBuilder<TranscodeType> load(@Nullable byte[] model) {
return loadGeneric(model).apply(signatureOf(new ObjectKey(UUID.randomUUID().toString()))
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true));
}
-
loadGeneric(Object model)方法很简单,将传入的model赋值给RequestBuilder的成员变量,并设置赋值的标志位为true。
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
- 综上可以看出,经过
load()方法会创建并返回一个RequestBuilder方法,并把load()中的参数图片源传递进去。
into()源码解析
- 上面的
load()方法返回了一个RequestBuilder方法,然后调用其中的into(),通过下面的into()进行,首先会进行是否有图片数据源和ScaleType的判断,会根据我们XML里面设置的ScaleType会做相应的设置,所以如果我们xml已经设置了,就不要在使用Glide的时候再设置一遍,最后调用另外一个重载的into()方法。
public Target<TranscodeType> into(ImageView view) {
Util.assertMainThread();
Preconditions.checkNotNull(view);
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
if (requestOptions.isLocked()) {
requestOptions = requestOptions.clone();
}
switch (view.getScaleType()) {
case CENTER_CROP:
requestOptions.optionalCenterCrop();
break;
case CENTER_INSIDE:
requestOptions.optionalCenterInside();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
requestOptions.optionalFitCenter();
break;
case FIT_XY:
requestOptions.optionalCenterInside();
break;
case CENTER:
case MATRIX:
default:
// Do nothing.
}
}
return into(context.buildImageViewTarget(view, transcodeClass));
}
- 上述只是简单逻辑判断和设置,into方法也有两个重载,另外一个就是最后一行调用的
into(Y target),而这个参数是通过context.buildImageViewTarget(view, transcodeClass)来构造的实参。
而传入clazz参数就和我们调用asXXX()相关:
如果调用的是asBitmap传入的是Bitmap.class就返回BitmapImageViewTarget对象。
如果调用的是asDrawable传入的是Drawable.class,返回DrawableImageViewTarget对象。
如果调用的是asGif传入的是Drawable的子类GifDrawable,也返回DrawableImageViewTarget对象。
如果调用的是as(Class c),实参不是Bitmap或者不是Drawable的子类就会抛异常。
public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
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(Y traget)方法实现,先通过buildRequest方法构建了一个Request对象,先判断target是之前已经绑定了请求,如果旧请求和新请求一样且处于请求完成或者正在请求状态就直接复用旧请求。如果不复用,就RequestManager先移除和旧请求绑定的target对象,Target再重新和Request对象进行一个绑定,调用requestManager.track(target, request)再加入请求队列,开启请求,最后返回经过处理的traget对象。
public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
Util.assertMainThread();
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
requestOptions.lock();
Request request = buildRequest(target);
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)
&& (Preconditions.checkNotNull(previous).isComplete()
|| Preconditions.checkNotNull(previous).isRunning())) {
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);
return target;
}
- 通过上面分析可知
into方法中最关键的两处代码分别是buildRequest和requestManager.track,一个是构建请求,一个是执行请求,搞懂了这两处代码基本就搞懂了Glide请求图片的流程。
Request request = buildRequest(target);
requestManager.track(target, request);
- 下面来看看
buildRequest内部又调用了buildRequestRecursive方法,如下所示代码省略号部分是在处理缩略图,如果对这块不关注的话,可以看到最后调用了obtainRequest方法来返回一个Request对象。
private Request buildRequest(Target<TranscodeType> target) {
return buildRequestRecursive(target, null, transitionOptions, requestOptions.getPriority(),
requestOptions.getOverrideWidth(), requestOptions.getOverrideHeight());
}
private Request buildRequestRecursive(Target<TranscodeType> target,
@Nullable ThumbnailRequestCoordinator parentCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority, int overrideWidth, int overrideHeight) {
......
return obtainRequest(target, requestOptions, parentCoordinator, transitionOptions, priority,
overrideWidth, overrideHeight);
}
- 再深入进入
obtainRequest方法中看看,里面又调用了SingleReuqest.obtain方法,一环嵌套一环。
private Request obtainRequest(Target<TranscodeType> target,
RequestOptions requestOptions, RequestCoordinator requestCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions, Priority priority,
int overrideWidth, int overrideHeight) {
requestOptions.lock();
return SingleRequest.obtain(
context,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
requestListener,
requestCoordinator,
context.getEngine(),
transitionOptions.getTransitionFactory());
}
- 在这个方法里面可以看到创建了一个
SingleRequest对象,并进行了初始化,初始化主要是进行成员参数的一个赋值操作。至此我们弄清楚了Glide为我们构建了一个SingleRequest的请求对象,下面来看看是请求启动的过程。
public static <R> SingleRequest<R> obtain(
GlideContext glideContext,
Object model,
Class<R> transcodeClass,
RequestOptions requestOptions,
int overrideWidth,
int overrideHeight,
Priority priority,
Target<R> target,
RequestListener<R> requestListener,
RequestCoordinator requestCoordinator,
Engine engine,
TransitionFactory<? super R> animationFactory) {
@SuppressWarnings("unchecked") SingleRequest<R> request =
(SingleRequest<R>) POOL.acquire();
if (request == null) {
request = new SingleRequest<>();
}
request.init(
glideContext,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
requestListener,
requestCoordinator,
engine,
animationFactory);
return request;
}
- 通过对
requestManager.track(target, request);的追踪来看看,请求是如何被启动的。track方法中调用了runRquest方法,这就是启动Request的开关。
void track(Target<?> target, Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
- 在
runRequest中请求会加入请求队列,isPaused,这个状态是根据生命周期挂钩的,如果处于暂停状态,就先将请求放入待处理队列;如果不是可以调用begin方法开始请求,这里的request就是我们上面创建并返回的SimpleRequest对象。
public void runRequest(Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
pendingRequests.add(request);
}
}
- 下面来看看
SimpleRquest中的begin方法,首先判断model是否为空,model就是我们load方法中传入的对象,如果为空,就看有没有设置好的错误图片可以使用,如果有就显示错误图片,再判断是否有占位图,如果有就显示占位图,注意如果如果既设置了占位图又设置了占位图,优先显示占位图。
如果请求已经在运行了,会抛出异常,因为不可重复启动请求。
如果请求已经完成了,这时候又发送了一个相同的请求加载到一样的View中,就会取最新一次请求获取的资源和大小,让View重新加载一遍,就不重新进行请求了,节约资源。
如果以上条件都符合,是一个新的合法请求,会先判断加载的长宽是否合法,如果合法会调用onSizeReady方法,如果不合法会经过计算也会调用onSizeReady方法。
还有需要注意下面调用的onLoadStarted只是设置了占位图了,并不是真正开启来请求的加载。
public void begin() {
stateVerifier.throwIfRecycled();
startTime = LogTime.getLogTime();
if (model == null) {
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
width = overrideWidth;
height = overrideHeight;
}
int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
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);
return;
}
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
target.getSize(this);
}
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("finished run method in " + LogTime.getElapsedMillis(startTime));
}
}
-
onSizeReady方法修改status为RUNNING的状态,其次获取长度和宽度,通过传入所有参数到engine.load方法,开始加载图片。
egine是Engine的对象,专门负责负责启动加载过程并管理正在显示的图片资源和已经缓存图片资源。
public void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
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.getOnlyRetrieveFromCache(),
this);
}
- 在
load方法中主要分别创建了EngineJob和DecodeJob的对象
EngineJob负责管理加载回调函数,可以添加和移除回调函数,并且当加载完成之后会调用。
DecodeJob负责缓存和网络请求资源。
public <R> LoadStatus load(...) {
......
EngineJob<R> engineJob = engineJobFactory.build(key, isMemoryCacheable,
useUnlimitedSourceExecutorPool);
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);
engineJob.start(decodeJob);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Started new load", startTime, key);
}
return new LoadStatus(cb, engineJob);
}
- 来看一下
engineJob.start(decodeJob)中的代码, 会调用父类ThreadPoolExecutor的的execute的方法,传入的是实现了Runnable接口的类,decodeJob实现了Runnable接口,因此调用是decodeJob中的run方法
public void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
executor.execute(decodeJob);
}
public void execute(Runnable command) {
if (executeSynchronously) {
command.run();
} else {
super.execute(command);
}
- 看一下
decodeJob中的run方法,发现主要调用的是runWrapped方法
public void run() {
TraceCompat.beginSection("DecodeJob#run");
try {
if (isCancelled) {
notifyFailed();
return;
}
runWrapped();
} catch (RuntimeException e) {
.....
}
} finally {
......
}
}
-
runWrapped方法中有四种类型,刚开始肯定是INITIALIZE,所以分别看一下这个三个方法
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);
}
}
- 第一个方法
getNextStage(Stage.INITIALIZE),getNextStage中如果是INITIALIZE,会调用decodeCachedResource函数根据返回的bool值来判断返回的状态,由于diskCacheStrategy是DiskCacheStrategy的对象,decodeCachedResource固定返回true,因此将会返回RESOURCE_CACHE状态。
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:
return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
case SOURCE:
case FINISHED:
return Stage.FINISHED;
default:
throw new IllegalArgumentException("Unrecognized stage: " + current);
}
}
public boolean decodeCachedResource() {
return true;
}
- 当调用完
getNextStage(Stage.INITIALIZE)方法后,stage的状态变成了RESOURCE_CACHE,接下来调用getNextGenerator方法,也是根据stage的判断生成不同的对象,根据当前stage为RESOURCE_CACHE状态创建了ResourceCacheGenerator对象
这三个Generator分别代表的含义是:
-
ResourceCacheGenerator:表示从已经处理过的缓存获取数据,比如缩略图,进行放大缩小等图片处理
-
DATA_CACHE: 表示从原始缓存加载数据。
-
SOURCE: 表示从数据源加载数据
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);
}
}
- 上面知道了
currentGenerator被赋值为ResourceCacheGenerator的对象,下面执行第三步runGenerators(),会发现进去了一个while循环,正常情况下前半部分条件肯定是满足的,关键后半部分
currentGenerator.startNext()。
在ResourceCacheGenerator中``startNext主要判断的为是否缓存了处理过的图片,如果第一次加载肯定不满足,就接着调用上面的那两个方法,stage会再变成DATA_CACHE,currentGenerator被赋值为DataCacheGenerator的对象,继续判断是否有原始缓存,如果没有stage状态变成SOURCE, currentGenerator被赋值为SourceGenerator的对象,直接调用reschedule方法,然后return退出。
所以加载图片的顺序是处理过的缓存图片-原始缓存图片-从数据源获取图片,如网络加载。
private void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
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();
}
}
- 在
reschedule方法中,runReason变成了SWITCH_TO_SOURCE_SERVICE,通过上面DecodeJob的函数callback就是传入的engineJob,reschedule方法就是又重新调用了一遍executor.execute(decodeJob),也就执行了run方法,又回到了runWrapped方法中,不过这时的runReason已经是SWITCH_TO_SOURCE_SERVICE,所以直接执行runGenerators方法,即开始执行
SourceGenerator的startNext方法
public void reschedule() {
runReason = RunReason.SWITCH_TO_SOURCE_SERVICE;
callback.reschedule(this);
}
- 下面来看看
SourceGenerator中的startNext方法
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;
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
return started;
}