Android圖片載入庫Picasso源碼分析

來源:互聯網
上載者:User

標籤:

圖片載入在Android開發中是非常重要,好的圖片載入庫也比比皆是。ImageLoader、Picasso、Glide、Fresco均是優秀的圖片載入庫。以上提到的幾種圖片載入庫各有特色。用法與比較,網上已經很多了。出於學習的角度,個人認為從Picasso入手較好。代碼量小,同時API優美,很適合我們學習。今天筆者就Picasso的源碼進行分析,拋出一些圖片載入的技術細節供園友參考。PS:建議園友先大致看一下源碼。我們對圖片載入的要求1.載入速度要快2.資源消耗要低3.載入圖片不能錯位 Picasso是否滿足要求?載入速度要快1.標配策略,MemoryCache+DiskCache+Net。提高載入速度,同時保證流量。2.Net部分,兼顧單請求載入速度與多請求並發能力,從而提高整體載入速度。3.MemoryCache部分,通過Lru策略提高緩衝效率。資源消耗要低1.渲染適當尺寸圖片來減少記憶體。2.通過線程池來限制並發的圖片載入線程,降低資源消耗。3.請求相同圖片的線程要合并,減少線程數。載入圖片不能錯位AdapterView會 複用View,Picasso通過Map<ImageView,Action>機制保證View展示正確的圖。 可見,Picasso已經滿足了我們對圖片載入的需求。 Picasso的一些基本策略緩衝策略 MemoryCache+DiskCache+Net1.MemoryCache採用的是Lru策略,持有一定數量處理過的圖(譬如經過resize/rotate處理,可直接設定到view中)。2.DiskCache是網狀圖片在本地的緩衝,緩衝的是原圖,可能需要經過處理才能設定到view中。3.Net是圖片伺服器,當MemoryCache和DiskCache均取不到圖片時,網路拉取,成本最高。圖片錯位為了保證圖片不會錯位,Picasso維護了Map<ImageView,Action>,每個ImageView均只對應一個Action。若擷取的圖片Action與ImageView不符合,則丟棄,等待正確的Action執行完。效能1.Picasso的線程池是最佳化過的,根據當前裝置網路狀況設定ThreadCount。在網路良好的條件下,線程池持有較多線程,保證下載速度夠快。在網路較差的條件下(2G網路等),線程池減少持有線程,保證頻寬不會被多個串連阻塞。2.Picasso將圖片uri、resize、transform等參數糅合為key,將key封裝到Action中進行請求。請求線程Hunter對相同key的Action進行合并,請求完成後,Action依次得到圖片。 以上是Picasso的一些基本策略,可能看不太懂,接下來結合 Picasso載入ImageView圖片的情境來串一下流程。流程與源碼分析執行個體化picasso的執行個體化有兩種方式1.Picasso.with(context)此方法提供預設,產生單例的Picasso對象。2.new Picasso.Builder(context).build()此方式提供自訂線程池、緩衝、下載器等方法。擷取RequestCreatorpicasso作為圖片載入庫,作用便是下載圖片。我們拿到picasso執行個體後,正常思路便是調用picasso.load()。load()有四個方法,參數各不相同,不過可以分為兩類:uri和resourceId。uri又分為file和net。load()的返回結果是RequestCreator對象,RequestCreator是用來配置載入參數的。RequestCreatorRequestCreator有兩個功能1.配置載入參數。包括placeHolder與error圖片,載入圖片的大小、旋轉、置中等屬性。2.執行載入。通過調用into(object)方法進行載入。  into方法主流程梳理如下後續的工作就交由Hunter來處理了備忘1:(imageview,action)是用來保證imageview與正確action匹配的。備忘2:hunterMap通過key持有多個hunter,同一個hunter可以對應多個actionHunterhunter是一個Runnable,作用是擷取圖片。hunter的執行流程:在run()方法中執行hunt()方法嘗試擷取圖片,結果(成功、失敗、異常)交給Dispatcher回調。hunter的基礎類是BitmapHunter,但它卻是一個模版類,最重要的decode(request)方法交由子類來實現。  hunt()方法主流程梳理如下:DispatcherDispatcher是分發器,由Picasso或Hunter來調用。Picasso或BitmapHunter只能調用dispatcher**()方法。原因是不能確定是main線程或Hunter線程在調用,所以Dispatcher索性對所有的調用均經過Dispatcher轉寄,轉寄後調用perform**()方法,這樣即可保證在main線程中操作事件。 API如下:dispatcherSubmit()和dispatcherCancel()hunter中加入action便調用dispatcherSubmit(),hunter中取消action便調用dispatcherCancel()dispatcherComplete()和dispatcherError()載入結束時調用。均調用batch方法,不過complete操作會將bitmap加入到cache中,以便後續調用。batch()起緩衝作用,每隔0.2s執行一次performBatchComplete()批處理。批處理將hunterList回調給Picasso,Picasso對每個hunter的每個action進行結果回調。 其他跟隨ImageView的圖片載入,應該對Picasso的源碼已經有了一定瞭解。但是還有幾個相對獨立的模組沒有涉及到,園友們直接閱讀源碼即可。downloader提供了UrlConnection和OKHttp兩種方案,優先選用OKHttp。主要添加了httpCache。Stats主要用於資料統計,很獨立的模組。   

Android圖片載入庫Picasso源碼分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.