我們直接來看Glide 是如何把網(wǎng)絡(luò)請求與Activity/Fragment的生命周期同步的卵慰,當(dāng)我們調(diào)用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的生命周期方法中調(diào)用了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();
}
}
那誰注冊了這個監(jiān)聽呢躯枢?那就是RequestManager,所以會調(diào)用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
}
調(diào)用request.begin()方法氓仲,相當(dāng)于調(diào)用了GenericRequest的onSizeReady()方法,接著調(diào)用Engine中的load()------
后面會說明glide中是如何完成整個請求得糜。同理敬扛,取消,暫停都是同樣的流程調(diào)用對應(yīng)的方法而已朝抖。
一個簡單的加載圖片舔哪。
Glide.with(context).load(url).placeholder(s).into(imageview)
首先,with()把網(wǎng)絡(luò)請求與生命周期聯(lián)結(jié)起來了槽棍。load()把url傳入了GenericRequestBuilder()賦值給model,placeholder()把把預(yù)覽圖片賦值給了placeholderId,into()最后組裝這些參數(shù)抬驴,具體調(diào)用過程:
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);? //?這里會調(diào)用到obtainRequest()將傳入GenericRequestBuilder的參數(shù),如model(url)封裝到request中布持。
target.setRequest(request);//這里把request作為tag與target綁定在了一起豌拙,
lifecycle.addListener(target);//添加到了lifecyle的實現(xiàn)類,也就是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());//在這里顯示設(shè)置的預(yù)加載圖片
}
}
--》onSizeReady()
public void onSizeReady (intwidth, intheight) {
ModelLoader modelLoader =loadProvider.getModelLoader();//DataLoadProvider接口的子類。根據(jù)model的類型胧卤,轉(zhuǎn)換得到不同的ModelLoader唯绍。
final DataFetcher dataFetcher = modelLoader.getResourceFetcher(model,width,height);//得到了一個對應(yīng)的加載器。如果model傳入的是個null,則會得到 NullFetcher枝誊。
ResourceTranscoder transcoder =loadProvider.getTranscoder(); //這個tanscoder可以把不同類型的圖片轉(zhuǎn)換况芒。
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);//先從內(nèi)存中加載。
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);//從網(wǎng)絡(luò)中加載
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);//這個回調(diào)會把正確的resource如(bitmap)設(shè)置到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);//加載器在這里會開始加載數(shù)據(jù)绝骚,如HttpUrlFetcher 返回值是輸入流
if(Log.isLoggable(TAG,Log.VERBOSE)) {
logWithTimeAndKey("Fetched data",startTime);
}
if(isCancelled) {
return null;
}
decoded = decodeFromSourceData(data);//對流進(jìn)行處理耐版,返回請求的資源,如bitmap
}finally{
fetcher.cleanup();
}
returndecoded;
}