Glide生命周期

我们直接来看Glide 是如何把网络请求与Activity/Fragment的生命周期同步的,当我们调用Glide.with()的时候,


public static RequestManager with(FragmentActivity activity) {

RequestManagerRetriever retriever = RequestManagerRetriever.get();

return retriever.get(activity);

}


--》get(activity)


publicRequestManagerget(FragmentActivity activity) {

if(Util.isOnBackgroundThread()) {

returnget(activity.getApplicationContext());

}else{

assertNotDestroyed(activity);

FragmentManager fm = activity.getSupportFragmentManager();

return supportFragmentGet(activity,fm);

}

}


--》supportFragmentGet(activity,fm);



RequestManager  supportFragmentGet(Context context,FragmentManager fm) {

SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);

RequestManager requestManager = current.getRequestManager();

if(requestManager ==null) {

requestManager =newRequestManager(context,current.getLifecycle(),current.getRequestManagerTreeNode());

current.setRequestManager(requestManager);//fragment的生命周期与RequestManger绑定

}

return requestManager;

}


会有一个SupportRequestManagerFragment与Activity的生命周期绑定,并且在里面有一个ActivityFragmentLifecycle  lifecycle的成员变量,SupportRequestManagerFragment的生命周期方法中调用了lifcylce的方法,如onStart(),这个时候,


public void onStart() {

super.onStart();

lifecycle.onStart();

}


就会遍历lifecycle的set<LifeCycleListener>集合,通知注册了LifecycleListener的对象,


void onStart() {

isStarted=true;

for(LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {

lifecycleListener.onStart();

}

}


那谁注册了这个监听呢?那就是RequestManager,所以会调用RequestManger的onStart()方法,


public void onStart() {

// onStart might not be called because this object may be created after the fragment/activity's onStart method.

resumeRequests();

}

public void resumeRequests() {

Util.assertMainThread();

requestTracker.resumeRequests();//后面会在into()方法中requestTracker.runRequest先把request添加set中,

}


但是RequestManager 也是交给RequestTracker的resumeRequests()方法处理,


public void resumeRequests() {

isPaused=false;

for(Request request : Util.getSnapshot(requests)) {

if(!request.isComplete() && !request.isCancelled() && !request.isRunning()) {

request.begin();

}

}

pendingRequests.clear();//这个pendingRequests集合中保存了未完成的request

}


调用request.begin()方法,相当于调用了GenericRequest的onSizeReady()方法,接着调用Engine中的load()------

后面会说明glide中是如何完成整个请求。同理,取消,暂停都是同样的流程调用对应的方法而已。


一个简单的加载图片。

Glide.with(context).load(url).placeholder(s).into(imageview)

首先,with()把网络请求与生命周期联结起来了。load()把url传入了GenericRequestBuilder()赋值给model,placeholder()把把预览图片赋值给了placeholderId,into()最后组装这些参数,具体调用过程:


into(ImageView view)--》

glide.buildImageViewTarget(view,transcodeClass)   将view封装成target --》

into(Y target)  在这个方法里面 :


Request previous = target.getRequest();   // 解决了图片加载错位的问题。

if(previous !=null) {

previous.clear();

requestTracker.removeRequest(previous);

previous.recycle();

}

Request request = buildRequest(target);  // 这里会调用到obtainRequest()将传入GenericRequestBuilder的参数,如model(url)封装到request中。

target.setRequest(request);//这里把request作为tag与target绑定在了一起,

lifecycle.addListener(target);//添加到了lifecyle的实现类,也就是ActivityFragmentLifecycle中的Set<LifecycleListener>中。

requestTracker.runRequest(request);


--》requestTracker.runRequest(request);   


requests.add(request);  //生命周期中讲到了在requestTracker中有一个集合

if(!isPaused) {

request.begin(); //在这里开始请求。

}else{

pendingRequests.add(request);

}


--》request.begin()


public void begin() {

onSizeReady(overrideWidth,overrideHeight);

if(!isComplete() && !isFailed() && canNotifyStatusChanged()) {

target.onLoadStarted(getPlaceholderDrawable());//在这里显示设置的预加载图片

}

}


--》onSizeReady()


public void onSizeReady (intwidth, intheight) {

ModelLoader modelLoader =loadProvider.getModelLoader();//DataLoadProvider接口的子类。根据model的类型,转换得到不同的ModelLoader。

final DataFetcher dataFetcher = modelLoader.getResourceFetcher(model,width,height);//得到了一个对应的加载器。如果model传入的是个null,则会得到 NullFetcher。

ResourceTranscoder transcoder =loadProvider.getTranscoder(); //这个tanscoder可以把不同类型的图片转换。

loadStatus=engine.load(signature,width,height,dataFetcher,loadProvider,transformation,transcoder

}


--》engine.load( )


public LoadStatus load(Key signature, intwidth, intheight,DataFetcher fetcher,

DataLoadProvider loadProvider,Transformation transformation,ResourceTranscoder transcoder,

Priority priority, booleanisMemoryCacheable,DiskCacheStrategy diskCacheStrategy,ResourceCallback cb) {

EngineKey key =keyFactory.buildKey()

EngineResource cached = loadFromCache(key,isMemoryCacheable);//先从内存中加载。

if(cached !=null) {

cb.onResourceReady(cached);

if(Log.isLoggable(TAG,Log.VERBOSE)) {

logWithTimeAndKey("Loaded resource from cache",startTime,key);

}

return null;

}

EngineResource active = loadFromActiveResources(key,isMemoryCacheable);//从本地加载

if(active !=null) {

cb.onResourceReady(active);

if(Log.isLoggable(TAG,Log.VERBOSE)) {

logWithTimeAndKey("Loaded resource from active resources",startTime,key);

}

return null;

}

EngineJob current =jobs.get(key);

if(current !=null) {

current.addCallback(cb);

if(Log.isLoggable(TAG,Log.VERBOSE)) {

logWithTimeAndKey("Added to existing load",startTime,key);

}

return newLoadStatus(cb,current);

}

EngineJob engineJob =engineJobFactory.build(key,isMemoryCacheable);

DecodeJob decodeJob =newDecodeJob(key,width,height,fetcher,loadProvider,transformation,

transcoder,diskCacheProvider,diskCacheStrategy,priority);

EngineRunnable runnable =newEngineRunnable(engineJob,decodeJob,priority);

jobs.put(key,engineJob);

engineJob.addCallback(cb);

engineJob.start(runnable);//从网络中加载

if(Log.isLoggable(TAG,Log.VERBOSE)) {

logWithTimeAndKey("Started new load",startTime,key);

}

return newLoadStatus(cb,engineJob);

}


--》engineJob.start(runnable);  启动 EngineRunnable  


public void run() {

resource = decode();//加载资源

if(resource ==null) {

onLoadFailed(exception);//加载失败的图片

}else{

onLoadComplete(resource);//这个回调会把正确的resource如(bitmap)设置到targetz中,最终完成显示到控件上面

}

}


--》decode()


private Resource decode()throwsException {

if(isDecodingFromCache()) {

return decodeFromCache();

}else{

return decodeFromSource();/

}

}


--》decodeFromSource()


publicResourcedecodeFromSource()throwsException {

Resource decoded = decodeSource();

return transformEncodeAndTranscode(decoded);

}


--》decodeSource()


privateResourcedecodeSource()throwsException {

Resource decoded =null;

try{

longstartTime = LogTime.getLogTime();

final A data =fetcher.loadData(priority);//加载器在这里会开始加载数据,如HttpUrlFetcher 返回值是输入流

if(Log.isLoggable(TAG,Log.VERBOSE)) {

logWithTimeAndKey("Fetched data",startTime);

}

if(isCancelled) {

return null;

}

decoded = decodeFromSourceData(data);//对流进行处理,返回请求的资源,如bitmap

}finally{

fetcher.cleanup();

}

returndecoded;

}


以上就是加载一张普通图片的基本调用流程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容