一.glide基礎三步走:先with(),然後load(),最後into()。

1.with():可以傳入activity,fragment,context

在Glide中調用RequestManagerRetriever的get方法,在get方法中傳入context,或activity或fragment,最終會返回一個RequestManager對象。

如果是applicationContext則不需要特殊操作直接調用getApplicationManager創建RequestManager對象,生命週期則和應用程序生命週期一致

如果是activity或者fragment則supportFragmentGet或者fragmentGet,注意這裏如果判斷不是主線程則調用的還是與application綁定生命週期的方法。在或者fragmentGet中會創建一個fragment用於監聽生命週期。

2.load():Glide支持加載各種各樣的圖片資源,包括網絡圖片、本地圖片、應用資源、二進制流、Uri對象等等。因此load()方法也有很多個方法重載,此處分析的是加載網絡圖片的url。

RequestManager中調用(DrawableTypeRequest) fromString().load(string)方法

formString中會得到不同的ModelLoader,ModelLoader對象是用來加載圖片的,最終返回的是DrawableTypeRequest對象

然後看DrawableTypeRequest對象可以看出裏面有asBitmap和asGif,他們分別創建了一個BitmapTypeRequest和GifTypeRequest,如果沒有強制規定則還是DrawableTypeRequest對象。

然後看DrawableTypeRequest對象的父類DrawableRequestBuilder,可以看見load方法在此處並且返回自身,然後還有其他擴展的功能方法也都在此處,比如説placeholder()方法、error()方法、diskCacheStrategy()方法、override()方法等。當然還有into方法。

3.into():

DrawableTypeRequest——————>父類DrawableRequestBuilder——————>父類GenericRequestBuilder執行into(glide.buildImageViewTarget(view, transcodeClass))

glide.buildImageViewTarget(view, transcodeClass)——————>ImageViewTargetFactory的buildTarget(imageView, transcodedClass):意義就是根據transcodedClass生成不同的對象,一般情況下調用asBitmap則是BitmapImageViewTarget對象,否則是GlideDrawableImageViewTarget對象

into(glide.buildImageViewTarget(view, transcodeClass))——————>GenericRequestBuilder的into(Y target)方法,此方法內容很多其中主要兩行代碼是buildRequest()和執行request方法requestTracker.runRequest(request);

buildRequest調用buildRequestRecursive方法,此方法大部分代碼是用來執行縮略圖的操作的,只看主線調用了obtainRequest方法,此方法調用了GenericRequest.obtain,在GenericRequest.obtain中new一個GenericRequest對象,並且調用init方法做了許多賦值的操作。

requestTracker.runRequest(request)不是暫停狀態調用——————>GenericRequest的begin方法——————>model==null調用onException方法,model!=null如果設置了寬高調用onSizeReady(overrideWidth, overrideHeight),沒有設置寬高調用target.getSize(this)方法

onException方法—————>setErrorPlaceholder(Exception e)方法,其中邏輯是先獲取error的佔位圖賦值給error,如果獲取不到則獲取loading佔位圖賦值給error並且傳入下一個方法中————>target.onLoadFailed(e, error)————>view.setImageDrawable(errorDrawable)就是為了在ImageView中顯示加載錯誤

target.getSize(this)中根據ImageView寬高的計算最終調用的還是onSizeReady()方法

onSizeReady(overrideWidth, overrideHeight)12行中調用了loadProvider.getModelLoader(),loadProvider是什麼需要在load加載邏輯之前的DrawableTypeRequest中的構造函數中去尋找答案。

DrawableTypeRequest中的構造函數中29行buildProvider(glide, streamModelLoader, fileDescriptorModelLoader, GifBitmapWrapper.class,GlideDrawable.class, null),這兩個ModelLoader就是之前在loadGeneric()方法中構建出來的

buildProvider在第16行調用了glide.buildTranscoder()方法來構建一個ResourceTranscoder,它是用於對圖片進行轉碼的,由於ResourceTranscoder是一個接口,這裏實際會構建出一個GifBitmapWrapperDrawableTranscoder對象

接下來在第18行調用了glide.buildDataProvider()方法來構建一個DataLoadProvider,它是用於對圖片進行編解碼的,由於DataLoadProvider是一個接口,這裏實際會構建出一個ImageVideoGifDrawableLoadProvider對象。

然後在第20行,new了一個ImageVideoModelLoader的實例,並把之前loadGeneric()方法中構建的兩個ModelLoader封裝到了ImageVideoModelLoader當中。

最後,在第22行,new出一個FixedLoadProvider,並把剛才構建的出來的GifBitmapWrapperDrawableTranscoder、ImageVideoModelLoader、ImageVideoGifDrawableLoadProvider都封裝進去,這個也就是onSizeReady()方法中的loadProvider了。

onSizeReady(overrideWidth, overrideHeight)13行調用了ImageVideoModelLoader的getResourceFetcher()方法————>在第20行會先調用streamLoader.getResourceFetcher()方法獲取一個DataFetcher,而這個streamLoader其實就是我們在loadGeneric()方法中構建出的StreamStringLoader,調用它的getResourceFetcher()方法會得到一個HttpUrlFetcher對象。然後在第28行new出了一個ImageVideoFetcher對象,並把獲得的HttpUrlFetcher對象傳進去。也就是説,ImageVideoModelLoader的getResourceFetcher()方法得到的是一個ImageVideoFetcher。

onSizeReady(overrideWidth, overrideHeight)23行將剛才獲得的ImageVideoFetcher、GifBitmapWrapperDrawableTranscoder等等一系列的值一起傳入到了Engine的load()方法當中,load大部分代碼用來處理緩存的。這裏構建了一個EngineJob,它的主要作用就是用來開啓線程的,為後面的異步加載圖片做準備。接下來第46行創建了一個DecodeJob對象,從名字上來看,它好像是用來對圖片進行解碼的,但實際上它的任務十分繁重,待會我們就知道了。繼續往下看,第48行創建了一個EngineRunnable對象,並且在51行調用了EngineJob的start()方法來運行EngineRunnable對象,這實際上就是讓EngineRunnable的run()方法在子線程當中執行了。

EngineRunnable的run()方法————>第9行從緩存取調用decodeFromCache,否則調用decodeFromSource方法

decodeFromSource主要是兩步,一步是獲取Resource對象,第二步是transformEncodeAndTranscode方法來處理Resource對象

第一步獲取Resource對象,第14行fetcher.loadData()————>ImageVideoFetcher的loadData方法————>HttpUrlFetcher的loadData方法

ImageVideoFetcher的loadData方法返回值是ImageVideoWrapper對象調用decodeSource的21行方法decodeFromSourceData並將ImageVideoWrapper對象傳進去-————>這裏在第7行調用了loadProvider.getSourceDecoder().decode()方法來進行解碼。loadProvider就是剛才在onSizeReady()方法中得到的FixedLoadProvider,而getSourceDecoder()得到的則是一個GifBitmapWrapperResourceDecoder對象,也就是要調用這個對象的decode()方法來對圖片進行解碼————>GifBitmapWrapperResourceDecoder的decode方法然後在第23行調用了decodeStream()方法,準備從服務器返回的流當中讀取數據。decodeStream()方法中會先從流中讀取2個字節的數據,來判斷這張圖是GIF圖還是普通的靜圖,如果是GIF圖就調用decodeGifWrapper()方法來進行解碼,如果是普通的靜圖就用調用decodeBitmapWrapper()方法來進行解碼。這裏我們只分析普通靜圖的實現流程,GIF圖的實現有點過於複雜了

decodeBitmapWrapper52行————>ImageVideoBitmapDecoder的decode()方法————>14行調用source.getStream()獲得InputStream,17行調用streamDecoder.decode()進行解碼,streamDecoder是StreamBitmapDecoder,streamDecoder.decode()中是對服務器返回的InputStream的讀取,以及對圖片的加載全都在這裏了。當然這裏其實處理了很多的邏輯,包括對圖片的壓縮,甚至還有旋轉、圓角等邏輯處理,但是我們目前只需要關注主線邏輯就行了。decode()方法執行之後,會返回一個Bitmap對象,那麼圖片在這裏其實也就已經被加載出來了,剩下的工作就是如果讓這個Bitmap顯示到界面上。

回到剛才的StreamBitmapDecoder當中,你會發現,它的decode()方法返回的是一個Resource對象。而我們從Downsampler中得到的是一個Bitmap對象,因此這裏在第18行又調用了BitmapResource.obtain()方法,將Bitmap對象包裝成了Resource對象

然後我們需要一層層繼續向上返回,StreamBitmapDecoder會將值返回到ImageVideoBitmapDecoder當中,而ImageVideoBitmapDecoder又會將值返回到GifBitmapWrapperResourceDecoder的decodeBitmapWrapper()方法當中。

GifBitmapWrapper將Resource封裝到GifBitmapWrapper對象中,返回到GifBitmapWrapperResourceDecoder最外層的decode()方法的時候,會對它再做一次封裝

經過這一層的封裝之後,我們從網絡上得到的圖片就能夠以Resource接口的形式返回,並且還能同時處理Bitmap圖片和GIF圖片這兩種情況。

那麼現在我們可以回到DecodeJob當中了,它的decodeFromSourceData()方法返回的是一個Resource對象,其實也就是Resource對象了。然後繼續向上返回,最終返回到decodeFromSource()方法當中。

decodeFromSource()方法最終返回的卻是一個Resource對象?——————>transformEncodeAndTranscode(decoded)————>transcoder.transcode(transformed)————>GifBitmapWrapperDrawableTranscoder轉碼的作用

EngineRunnable run()————>onLoadComplete(resource)加載完成————>manager.onResourceReady(resource)———>handler發送MSG_COMPLETE消息———>切換到主線程————>buildImageViewTarget()————>GlideDrawableImageViewTarget————>ImageViewTarget ————————————————

版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

原文鏈接:https://blog.csdn.net/gongjdde/article/details/106504540