Android圖片載入庫Picasso原始碼分析
圖片載入在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+Net
1.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()
此方式提供自定義執行緒池、快取、下載器等方法。
獲取RequestCreator
picasso作為圖片載入庫,作用便是下載圖片。我們拿到picasso例項後,正常思路便是呼叫picasso.load()。
load()有四個方法,引數各不相同,不過可以分為兩類:uri和resourceId。uri又分為file和net。
load()的返回結果是RequestCreator物件,RequestCreator是用來配置載入引數的。
RequestCreator
RequestCreator有兩個功能
1.配置載入引數。
包括placeHolder與error圖片,載入圖片的大小、旋轉、居中等屬性。
2.執行載入。
通過呼叫into(object)方法進行載入。
into方法主流程梳理如下
後續的工作就交由Hunter來處理了
備註1:(imageview,action)是用來保證imageview與正確action匹配的。
備註2:hunterMap通過key持有多個hunter,同一個hunter可以對應多個action
Hunter
hunter是一個Runnable,作用是獲取圖片。
hunter的執行流程:在run()方法中執行hunt()方法嘗試獲取圖片,結果(成功、失敗、異常)交給Dispatcher回撥。
hunter的基礎類是BitmapHunter,但它卻是一個模版類,最重要的decode(request)方法交由子類來實現。
hunt()方法主流程梳理如下:
Dispatcher
Dispatcher是分發器,由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主要用於資料統計,很獨立的模組。
相關文章
- 圖片載入框架Picasso - 原始碼分析框架原始碼
- 圖片載入框架Picasso原始碼分析框架原始碼
- Android圖片載入框架Picasso原始碼分析(基於Picasso 2.71828)Android框架原始碼
- Picasso 載入圖片的流程分析
- Android 圖片載入框架 Picasso 基本使用和原始碼完全解析Android框架原始碼
- 簡單說說我最常用的圖片載入庫 Picasso
- Google推薦的圖片載入庫Glide於Picasso比較GoIDE
- Android:這是一份全面 & 詳細的圖片載入庫Glide原始碼分析AndroidIDE原始碼
- 圖片載入利器之Picasso(五)查漏補缺
- 影片直播原始碼,載入gif圖片原始碼
- 圖片載入框架-Picasso最詳細的使用指南框架
- Architecture(3)Picasso原始碼分析原始碼
- Android Volley 原始碼解析(三),圖片載入的實現Android原始碼
- Android 載入大圖片時報OOM的解決方案(原始碼)AndroidOOM原始碼
- FaceBook推出的Android圖片載入庫FrescoAndroid
- Android 圖片載入框架Android框架
- android 載入大量圖片Android
- Android圖片載入記憶體佔用分析Android記憶體
- 視訊直播app原始碼,Android RecyclerView 列表載入圖片寬高適配APP原始碼AndroidView
- 解耦圖片載入庫解耦
- Android 載入大圖片,不壓縮圖片Android
- Android 高效安全載入圖片Android
- Android常用圖片載入庫介紹及對比Android
- Android應用開發-圖片載入庫GlideAndroidIDE
- Android 自定義本地圖片載入庫,仿微信相簿Android地圖
- 小說APP原始碼的圖片載入方式,懶載入和預載入的實現APP原始碼
- javascript圖片懶載入與預載入的分析JavaScript
- Android 圖片載入庫Glide知其然知其所以然之載入AndroidIDE
- android glide圖片載入框架AndroidIDE框架
- Android圖片載入開源庫深度推薦,安利FrescoAndroid
- jQuery圖片預載入程式碼jQuery
- Android ImageLoader框架之圖片載入與載入策略Android框架
- Android 基礎之圖片載入(二)Android
- Android偽圖片載入進度效果Android
- iOS非同步圖片載入優化與常用開源庫分析iOS非同步優化
- Picasso-原始碼解析(二)原始碼
- Picasso-原始碼解析(三)原始碼
- Picasso-原始碼解析(一)原始碼