1.主要涉及到的類,以及該類的具體操作邏輯
1)Picasso、Picasso.Builder ?Builder是Picasso的內(nèi)部類,主要作用是用來創(chuàng)建Picasso對(duì)象的。創(chuàng)建對(duì)象需要以下幾個(gè)對(duì)象
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。
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中。
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集合中移除。
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)系人。
創(chuàng)建picasso對(duì)象的時(shí)候回創(chuàng)建7種requestHandler,如下圖:
5) 網(wǎng)絡(luò)加載完成之后回調(diào)到Dispacher的一些操作
a.緩存到內(nèi)存當(dāng)中
b.移除dispatcher中BitmapHunter ,通過handler的hasmessages方法來批量處理一批圖片,處理完成之后也馬上就會(huì)相應(yīng)的清除。
c.將批量的hunter通過mainThreadHandler發(fā)送到Picasso中處理,并清空處理批零緩存的hunter。
d.Picasso收到HUNTER_BATCH_COMPLETE消息后會(huì)在hunter.picasso.complete(hunter)調(diào)用方法deliverAction方法,將bitmap加載到Action上。這里我們主要看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。
從圖中我們看到,有去調(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。