Glide主要用法就是Glide.with(context).load(xx).into(xx)。
with(context)
我们首先要做得就是分析with做了什么, with 当我们传入的是一个非Application且线程在主线程的时候glide会帮我们初始化一个空白的fragment与当前页面绑定。
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
@NonNull
public RequestManager get(@NonNull 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);
}
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable 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;
}
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
//双重判断,保证了一个Fragment
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;
}
当绑定完成后,with这块逻辑也基本结束,返回requestManager,同时保证了一个fragment 一个requestManager。我们接下来再稍微分析下这个fragment。 这个fragment 没有setcotentview,只实现了几个生命周期 onAttach onstart onStop onDestory
@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();
}
这里涵盖了为什么glide要做这件事,其中lifecycle实现类是ActivityLifecycle,代码很清晰,我就不贴出来了,主要就是里面有Set类 接收LifecycleListener,之后在生命周期中,返回这些回调。这样就实现了不需要我们在代码中生命周期里实现绑定和解绑,glide完全帮我们做了这件事。到这里,with的逻辑基本分析到这。
load&&into
load 这里面逻辑很简单,构造了一个RequestBuilder对象,将里面赋值,主要是into,我们先考虑的是String- ImageView的逻辑。如果是ImageView的话into会走到一个glideContext.buildImageViewTarget(view, transcodeClass)方法里,返回的是DrawableImageViewTarget。 最后会调到这里。
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
// 一步步跟进,最后实现方法是SingleRequest.obtain
Request request = buildRequest(target, targetListener, options, callbackExecutor);
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
// 重要的在这
requestManager.clear(target); // 清空target任务
target.setRequest(request); // 重新绑定新任务
requestManager.track(target, request);
}
// RequestManager
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
// 这个地方也是绑定lifecycle接口,从RequestManager那里绑定的,targetTracker集中处理。通俗的说就是 这个地方将drawableImageViewTarget的lifecycle接口与supprotFragment的相通了。
targetTracker.track(target);
requestTracker.runRequest(request); // runRequest做了一件事放进集合,request.begin()ps.SingleRequest
}
// 校验都确认没问题的话,就会到这里,寻找资源 并实现了3级缓存。
public <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<?> memoryResource;
synchronized (this) {
// glide 内存缓存有两级
memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
if (memoryResource == null) {
return waitForExistingOrStartNewJob(
glideContext,
model,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
options,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache,
cb,
callbackExecutor,
key,
startTime);
}
}
return null;
}
// 最终会走到这里
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor =
decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
executor.execute(decodeJob);
}
//DecodeJob
@Override
public void run() {
runWrapped();
}
// SourceGenerator
private void startNextLoad(final LoadData<?> toStart) {
// 实现请求的地方
loadData.fetcher.loadData(
helper.getPriority(),
new DataCallback<Object>() {
@Override
public void onDataReady(@Nullable Object data) {
if (isCurrentRequest(toStart)) {
onDataReadyInternal(toStart, data);
}
}
@Override
public void onLoadFailed(@NonNull Exception e) {
if (isCurrentRequest(toStart)) {
onLoadFailedInternal(toStart, e);
}
}
});
}
走到这个地方的时候可能对这个fecher感到陌生,这个初始化的地方是在glide构建对象时候有一个注册机机制。可以在glide初始化的时候找到。
glide() {
registry.append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
}
之后
//SourceGenerator
private void startNextLoad(final LoadData<?> toStart) {
loadData.fetcher.loadData(
helper.getPriority(),
new DataCallback<Object>() {
@Override
public void onDataReady(@Nullable Object data) {
if (isCurrentRequest(toStart)) {
onDataReadyInternal(toStart, data);
}
}
@Override
public void onLoadFailed(@NonNull Exception e) {
if (isCurrentRequest(toStart)) {
onLoadFailedInternal(toStart, e);
}
}
});
}
//HttpUrlFetcher
@Override
public void loadData(
@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
long startTime = LogTime.getLogTime();
try {
InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
callback.onDataReady(result);
} catch (IOException e) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Failed to load data for url", e);
}
callback.onLoadFailed(e);
} finally {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Finished http url fetcher fetch in " + LogTime.getElapsedMillis(startTime));
}
}
}
这就找到了网络请求的地方,之后请求完成后,之后原路返回至decodeJob 开始解码,之后会将结果保存在内存的二级缓存中,之后一步步的回调返回至target的onResourceReady 至此 glide整个流程结束。
glide源码太多,有说的不对的地方,还请各位大佬给与批评指正。