我們直接來看Glide 是如何把網(wǎng)絡請求與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();
}
}
那誰注冊了這個監(jiān)聽呢?那就是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()把網(wǎng)絡請求與生命周期聯(lián)結起來了。load()把url傳入了GenericRequestBuilder()賦值給model,placeholder()把把預覽圖片賦值給了placeholderId,into()最后組裝這些參數(shù),具體調用過程:
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的參數(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());//在這里顯示設置的預加載圖片
}
}
--》onSizeReady()
public void onSizeReady (intwidth, intheight) {
ModelLoader modelLoader =loadProvider.getModelLoader();//DataLoadProvider接口的子類。根據(jù)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);//從網(wǎng)絡中加載
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);//加載器在這里會開始加載數(shù)據(jù),如HttpUrlFetcher 返回值是輸入流
if(Log.isLoggable(TAG,Log.VERBOSE)) {
logWithTimeAndKey("Fetched data",startTime);
}
if(isCancelled) {
return null;
}
decoded = decodeFromSourceData(data);//對流進行處理,返回請求的資源,如bitmap
}finally{
fetcher.cleanup();
}
returndecoded;
}