Picasso使用的是門面設計模式,Picasso的調用是從Picasso這個類中開始的,Picasso內部組件的初始化也是從這個類中開始的,如果需要自定義Picasso,可以通過Picasso.with("環境上下文")來獲取的Picasso的實例。Picasso的實例使用了單例設計模式
Picasso加載圖片使用的是Okhhtp和HttpConnection兩種方式,使用的時候Picasso通過反射來判斷當前是否存在Okhttp的依賴包,如果存在就使用,不存在則使用HttpConnetion來請求圖片
圖片的存儲路徑是data/data/包名,不同品牌的手機的該路徑不同,因此 通過環境上下文來來獲取該路徑this.getCacheDir();通常使用Application來獲取該路徑。
圖片內存中緩存的算法默認使用的是LruCache,在內存的容量達到峰值的時候,默認移除最早的緩存
Picasso中存在接受網絡狀況改變的廣播,因此可以根據當前的網絡狀況來來決定當前的線程池中線程的個數:
網絡狀況特別好(列入Wifi) 線程池中線程的個數為4
網絡狀況好(4G) 線程池中的線程的個數為3
網絡狀況一般(3G)線程池中線程的個數為2;
網絡狀況不好(2G)線程池中線程的個數為1
默認狀態下的線程池中的線程的個數為3.
圖片的加載流程:
Picasso通過with()來獲取到Picasso的單列,通過Load()方法封裝了圖片的請求參數,例如URl,圖片的請求參數,圖片請求的優先級等,通過該方法后得到的返回的對象可以用來設置圖片的其他參數,例如error時的圖片,占位圖片等,最終通過設置into()方法來創建一個請求,通過action把意圖和內存策略以及target封裝后,提交給Picasso執行類去執行,通過target來判斷,target是否已存在action,如果是則pause之前的target,然后Picasso類把任務的啟動交給dispatcher來執行,dispatcher檢查action對應的hunter是否已創建,如果創建則直接將actionattachhunter即可,如果hunter沒有創建則創建hunter并將其提交給線程池執行.執行完成后通過在BitmapHunter獲取圖片成功后,會交由dispatcher.dispatchComplete(this);dispatcher會將200ms內完成的任務發送到主線程(這個主線程handler定義在Picasso類中),在這里有一個延遲(不知道為什么)主線程收到這個消息后會調用complete方法,action.complete(result, from);會被調用,在這個方法里面會對target設置bitmap(還有些加載動畫等設置,此處不再贅述),至此圖片加載完成。
圖片加載的詳細流程
Picasso獲取圖片資源并顯示的代碼流轉過程如下:
Picasso.with()獲取Picasso實例
.load("url")方法用傳入的url創建一個RequestCreator對象
.into(imageview)方法創建此次request并將其封裝進action再調用picasso.enqueueAndSubmit(action)
Picasso類將action對象交給dispatcher.submit()
dispatcher類根據action創建bitmapHunter,并將bitmapHunter提交至線程池執行
當bitmapHunter獲取到圖片資源后,又經過了以下步驟最終顯示在ImageView上
bitmapHunter獲取圖片資源成功,調用dispatcher.dispatchComplete(this);
dispatcher發送延遲200ms、msg.what=HUNTER_DELAY_NEXT_BATCH、攜帶200ms內完成的bitmapHunter封裝為一個list的消息到主線程
主線程收到消息后,調用Picasso類的complete方法,解析出bitmapHunter中的action
action的complete方法內,將bitmap設置給Imageview