Android _ 《看完不忘系列》之Glide

Glide glide = Glide.get(context);
//如果空fragment没有RequestManager,就创建一个
requestManager = factory.build(glide, current.getGlideLifecycle(),
current.getRequestManagerTreeNode(), context);
//让空fragment持有RequestManager
current.setRequestManager(requestManager);
}
//返回页面级别的RequestManager
return requestManager;
}
}`

然后看到getSupportRequestManagerFragment方法,

class RequestManagerRetriever implements Handler.Callback { Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments = new HashMap<>(); SupportRequestManagerFragment getSupportRequestManagerFragment( final FragmentManager fm, Fragment parentHint, boolean isParentVisible) { //通过tag找到Activity中的空fragment SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG); if (current == null) { //findFragmentByTag没找到空fragment,有可能是延迟问题?再从Map中找一下 current = pendingSupportRequestManagerFragments.get(fm); if (current == null) { //确实没有空fragment,就创建一个 current = new SupportRequestManagerFragment(); //... //缓存进Map pendingSupportRequestManagerFragments.put(fm, current); //空fragment添加到Activity,使其能感知Activity的生命周期 fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss(); //... } } return current; } }

综上,通过with操作,

当context是app时,得到应用级别RequestManager全局单例;

当context是Activity时,每个页面都会被添加一个空fragment,由空fragment持有页面级别RequestManager

注意:如果with发生在子线程,不管context是谁,都返回应用级别RequestManager单例。

发散:添加空fragment来感知页面生命周期的思想,在Lifecycle的实现中也可以看到,见[ReportFragment](()的injectIfNeededIn方法。(不过这个方法在Lifecycle的2.2.0版本中有所改动,Android 10开始的设备改成了使用Application.ActivityLifecycleCallbacks来感知,感兴趣可以康康)

至此,我们根据存款context买到了心仪的车RequestManager,下面开始上牌~

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WmZ3PVyU-1651894368815)(https://user-gold-cdn.xitu.io/2020/7/15/17351bf3c4419b10?imageView2/0/w/1280/h/960/ignore-error/1)]

load:上牌

load方法得到了一个RequestBuilder图片请求构建器,见名知意猜一下,是用来创建图片请求的,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Yd1Z6Ut-1651894368816)(https://user-gold-cdn.xitu.io/2020/7/15/17351bf3c6376312?imageView2/0/w/1280/h/960/ignore-error/1)]

class RequestManager implements ComponentCallbacks2, LifecycleListener, ModelTypes<RequestBuilder<Drawable>> { RequestBuilder<Drawable> load(String string) { return asDrawable().load(string); } RequestBuilder<Drawable> asDrawable() { //需要加载的类型为Drawable return as(Drawable.class); } <ResourceType> RequestBuilder<ResourceType> as(Class<ResourceType> resourceClass) { //创建一个请求构建器 return new RequestBuilder<>(glide, this, resourceClass, context); } }

然后跟进asDrawable().load(string)

class RequestBuilder<TranscodeType> extends BaseRequestOptions<RequestBuilder<TranscodeType>> implements Cloneable, ModelTypes<RequestBuilder<TranscodeType>> { RequestBuilder<TranscodeType> load(String string) { return loadGeneric(string); } RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) { //只是简单地赋值 this.model = model; isModelSet = true; return this; } }

到这里,我们就完成了上牌,得到了一个RequestBuilder图片请求构建器。没错,上牌就这么简单,毕竟摇号已经够艰难了对吧?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wvKuc2Vp-1651894368816)(https://user-gold-cdn.xitu.io/2020/7/15/17351bf3cbd9f2d6?imageView2/0/w/1280/h/960/ignore-error/1)]

into:发车

阶段一

来到into了,

class RequestBuilder<TranscodeType> extends BaseRequestOptions<RequestBuilder<TranscodeType>> implements Cloneable, ModelTypes<RequestBuilder<TranscodeType>> { ViewTarget<ImageView, TranscodeType> into(ImageView view) { //... BaseRequestOptions<?> requestOptions = this; if (!requestOptions.isTransformationSet() && requestOptions.isTransformationAllowed() && view.getScaleType() != null) { //根据ImageView的ScaleType,来配置参数 switch (view.getScaleType()) { case CENTER_CROP: requestOptions = requestOptions.clone().optionalCenterCrop(); break; case CENTER_INSIDE: requestOptions = requestOptions.clone().optionalCenterInside(); break; //... } } return into( //前面提到,Target是展示图片的载体,这里他封装了ImageView glideContext.build **《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》无偿开源 徽信搜索公众号【编程进阶路】** ImageViewTarget(view, transcodeClass),null, requestOptions,Executors.mainThreadExecutor()); } }

继续跟进into重载方法,

class RequestBuilder<TranscodeType> extends BaseRequestOptions<RequestBuilder<TranscodeType>> implements Cloneable, ModelTypes<RequestBuilder<TranscodeType>> { <Y extends Target<TranscodeType>> Y into(Y target,RequestListener<TranscodeType> targetListener, BaseRequestOptions<?> options,Executor callbackExecutor) { //... //创建图片请求 Request request = buildRequest(target, targetListener, options, callbackExecutor); //获取Target载体已有的请求 Request previous = target.getRequest(); //如果两个请求等效,并且xxx(先忽略) if (request.isEquivalentTo(previous) && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) { if (!Preconditions.checkNotNull(previous).isRunning()) { //启动异步请求 previous.begin(); } return target; } requestManager.clear(target); //图片载体绑定图片请求,即imageView setTag为request target.setRequest(request); //启动异步请求 requestManager.track(target, request); return target; } }

跟进requestManager.track(target, request)

//RequestManager.java void track(Target<?> target,Request request) { targetTracker.track(target); requestTracker.runRequest(request); } //RequestTracker.java void runRequest(Request request) { requests.add(request); if (!isPaused) { //开启图片请求 request.begin(); } else { request.clear(); //如果处于暂停状态,就把请求存起来,晚些处理 pendingRequests.add(request); } }

到这里,就启动了图片请求,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UZsPMrkM-1651894368817)(https://user-gold-cdn.xitu.io/2020/7/15/17351bf3eb65acdb?imageView2/0/w/1280/h/960/ignore-error/1)]

阶段二

那么,接下来重点关注的就是request.begin()了,

class SingleRequest<R> implements Request, SizeReadyCallback, ResourceCallback { void begin() { synchronized (requestLock) { //... if (Util.isValidDimensions(overrideWidth, overrideHeight)) { //如果已经有了明确的尺寸,开始加载 onSizeReady(overrideWidth, overrideHeight); } else { //没有的话先去获取尺寸,最终还是走onSizeReady target.getSize(this); } //... } } void onSizeReady(int width, int height) { synchronized (requestLock) { //... //engine.load,传了很多参数 loadStatus = engine.load(glideContext,model, requestOptions.getSignature(), this.width,this.height, requestOptions.getResourceClass(), transcodeClass,priority, requestOptions.getDiskCacheStrategy(), //... this,callbackExecutor); //... } } }

跟进engine.load

class Engine implements EngineJobListener,MemoryCache.ResourceRemovedListener, EngineResource.ResourceListener { <R> LoadStatus load( GlideContext glideContext, //... Executor callbackExecutor) { //... EngineResource<?> memoryResource; synchronized (this) { //从内存加载 memoryResource = loadFromMemory(key, isMemoryCacheable, startTime); if (memoryResource == null) { //如果内存里没有缓存,则加载 return waitForExistingOrStartNewJob( glideContext, model, //... key, startTime); } } cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE); return null; } <R> LoadStatus waitForExistingOrStartNewJob(...) { //... EngineJob<R> engineJob =engineJobFactory.build(...); DecodeJob<R> decodeJob =decodeJobFactory.build(...); jobs.put(key, engineJob); //添加回调,这个cb就是SingleRequest自己,todo1 engineJob.addCallback(cb, callbackExecutor); //engineJob开启decodeJob engineJob.start(decodeJob); return new LoadStatus(cb, engineJob); } }

DecodeJob是一个Runable,看看他的run方法,调用链如下:

DecodeJob.run -> DecodeJob.runWrapped -> DecodeJob.runGenerators ->

SourceGenerator.startNext -> SourceGenerator.startNextLoad ->

MultiModelLoader#MultiFetcher.loadData ->

HttpUrlFetcher.loadData

来到HttpUrlFetcher

class HttpUrlFetcher implements DataFetcher<InputStream> { void loadData(Priority priority, DataCallback<? super InputStream> callback) { try { //获取输入流,没有引入okhttp,则使用HttpURLConnection InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders()); //回调出去 callback.onDataReady(result); } catch (IOException e) { callback.onLoadFailed(e); } finally { } } }

到这里,网络请求就完成了,下面看看图片是怎么设置上去的,前边留了个todo1,

//添加回调,这个cb就是SingleRequest自己,todo1

callback就是SingleRequest,被回调前有一些对象包装、解码操作,暂不深究,来到SingleRequest

null, glideUrl.getHeaders());
//回调出去
callback.onDataReady(result);
} catch (IOException e) {
callback.onLoadFailed(e);
} finally {
}
}
}`

到这里,网络请求就完成了,下面看看图片是怎么设置上去的,前边留了个todo1,

//添加回调,这个cb就是SingleRequest自己,todo1

callback就是SingleRequest,被回调前有一些对象包装、解码操作,暂不深究,来到SingleRequest

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值