Picasso源碼學(xué)習(xí)

1.主要涉及到的類,以及該類的具體操作邏輯

1)Picasso、Picasso.Builder ?Builder是Picasso的內(nèi)部類,主要作用是用來創(chuàng)建Picasso對(duì)象的。創(chuàng)建對(duì)象需要以下幾個(gè)對(duì)象

Picasso對(duì)象創(chuàng)建

downloader:可以支持okHttp和HttpURLConnection,如果你的項(xiàng)目引用了okhttp那么就會(huì)首先使用,否者就使用HttpURLConnection。

cache:這里的cache是用于內(nèi)存緩存的,內(nèi)部使用LinkedHashMap實(shí)現(xiàn)的。

service:PicassoExecutorService繼承ThreadPoolExecutor,是用于下載圖片的線程池。里面實(shí)現(xiàn)了根據(jù)網(wǎng)絡(luò)狀態(tài)來分配多少的線程數(shù),同事也復(fù)寫了compareTo()方法,實(shí)現(xiàn)了線程的優(yōu)先級(jí)。

RequestTransformer:是一個(gè)接口,用來修改請(qǐng)求信息(還有點(diǎn)迷糊)。

Stats:我的理解就是內(nèi)存大小、下載次數(shù)、生成內(nèi)存快照等的統(tǒng)計(jì)類。

Dispatcher :通過Handler實(shí)現(xiàn)下載任務(wù)的分發(fā)和回調(diào),Dispatcher扮演者任務(wù)下載,以及下載完成回調(diào)等樞紐的關(guān)鍵位置。它吃有兩個(gè)handler,mainThreadHandler和DispatcherHandler。DispatcherHandler的作用主要負(fù)責(zé)分發(fā)加載、回調(diào)、寫入緩存操作等。mainThreadHandler從Dispatcher中獲取回來的的圖片信息顯示在控件上。以下是Dispatcher將BitmapHunter提交到線程池的關(guān)鍵代碼。這里如果已經(jīng)加載過得hunter會(huì)緩存一份在hunterMap中。當(dāng)hunter加載完圖片后會(huì)對(duì)應(yīng)移除響應(yīng)的hunter。

將BitmapHunter提交到線程池加載圖片

2)RequestCreator、Request、Action、DeferredRequestCreator

RequestCreator:通過picaasso.load()方法創(chuàng)建,RequestCreator內(nèi)部也有一個(gè)Builder,主要作用是通過Builder模式,Builder各種存放設(shè)置參數(shù)后,創(chuàng)建請(qǐng)求圖片的Request、Action和requestKey。最后通過picasso.enqueueAndSubmit(action);回到Picasso在到Dispatcher中。

enqueueAndSubmit方法

DeferredRequestCreator:用于延遲創(chuàng)建Request.當(dāng)在請(qǐng)求是使用了fit()方法,并且ImageView的width 和 height 為零,ImageView會(huì)添加ViewTreeObserver.OnPreDrawListener監(jiān)聽,當(dāng)繪制前獲取到寬高,在去創(chuàng)建Request和請(qǐng)求的requestKey。下圖picsso.defer方法會(huì)緩存DeferredRequestCreator對(duì)象。會(huì)在picasso.enqueueAndSubmit(action)方法是從map集合中移除。

DeferredRequestCreator創(chuàng)建和緩存

Request和Action:Request存放的是請(qǐng)求設(shè)置的一些配置參數(shù)。Action持有Request引用,也弱引用著ImageView,也存放了緩存的配置參數(shù)。

3)BitmapHunter 是實(shí)現(xiàn)了Runnable接口,當(dāng)提交的線程池后,當(dāng)執(zhí)行該加載線程時(shí),會(huì)執(zhí)行run方法。BitmapHunter的方法,執(zhí)行了一個(gè)hunt()方法。返回一個(gè)bitmap。

4)RequestHandler

在BitmapHunter的構(gòu)造方法中獲取了對(duì)應(yīng)的RequestHandler,該類有7個(gè)實(shí)現(xiàn)類,對(duì)應(yīng)的是資源,asset,網(wǎng)絡(luò),文件,media,聯(lián)系人。

通過循環(huán)獲取合適的ReqestHandler

創(chuàng)建picasso對(duì)象的時(shí)候回創(chuàng)建7種requestHandler,如下圖:

創(chuàng)建所有的requestHandler

5) 網(wǎng)絡(luò)加載完成之后回調(diào)到Dispacher的一些操作

a.緩存到內(nèi)存當(dāng)中

dispatcher緩存bitmap到內(nèi)存

b.移除dispatcher中BitmapHunter ,通過handler的hasmessages方法來批量處理一批圖片,處理完成之后也馬上就會(huì)相應(yīng)的清除。

批量處理hunter

c.將批量的hunter通過mainThreadHandler發(fā)送到Picasso中處理,并清空處理批零緩存的hunter。

清理批量處理時(shí)緩存的hunter

d.Picasso收到HUNTER_BATCH_COMPLETE消息后會(huì)在hunter.picasso.complete(hunter)調(diào)用方法deliverAction方法,將bitmap加載到Action上。這里我們主要看ImageViewAction的complete方法

抽象的acition加載完成
action實(shí)現(xiàn)類ImageViewAction的complete

到此picasso的圖片加載流程就到這里了,下邊說一下網(wǎng)絡(luò)層的一些操作

2.網(wǎng)絡(luò)層的操作

我們知道加載圖片在bitmapHunter中的hunt方法執(zhí)行的。hunt方法中有一個(gè)關(guān)鍵的代碼,如下:

RequestHandler.Result result =requestHandler.load(data,networkPolicy);

這段代碼就是前面我們談的中requestHandler來加載的,requestHandler在創(chuàng)建bitmapHunder對(duì)象的時(shí)候,就具體選擇出來要使用7中requestHandler中的哪一種,加載完成之后的bitmap就會(huì)放在Result中。在下邊我主要講一下NetworkRequestHandler。

NetworkRequestHandler的load方法

從圖中我們看到,有去調(diào)用了downloader的load方法。在前邊我們知道有兩種downloader。OkHttpDownloader和UrlConnectionDownloader。具體使用哪種,就看你項(xiàng)目中是否使用okHttp網(wǎng)絡(luò)加載框架,如果使用了就會(huì)優(yōu)先使用OkHttpDownloader,否則就是用UrlConnectionDownloader。通過load方法返回一個(gè)Response,我們就可以通過Response獲取到夾雜回來的圖片流信息。

3.總結(jié):

1、加載內(nèi)存緩存的地方有兩處,一個(gè)是在RequestCreator中,一處是下bitmapHunter的hunt()方法中。

2、dispacher將加載完成的bitmap通過handler回到主線程中。

3、簡(jiǎn)單寫一個(gè)加載鏈,一個(gè)簡(jiǎn)要的加載流程。

Picasso-->picasso.load-->RequestCreator-->requestCreator.into-->picasso-->Dispatcher-->dispatcher.performSubmit-->BitmapHunter-->ExecutorService-->bitmapHunter.run-->dispatcher-->mainThreadHandler-->picasso.complete-->Aciton。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容