轉載自csdn首頁移動開發
一 四大圖片緩存的基本信息
Universal ImageLoader 是很早開源的圖片緩存,在早期被很多應用使用。
Picasso 是 Square 開源的項目,且他的主導者是 JakeWharton,所以廣爲人知。
Glide 是 Google 員工的開源項目,被一些 Google App 使用,在去年的 Google I/O 上被推薦,不過目前國內資料不多。
Fresco 是 Facebook 在今年上半年開源的圖片緩存,主要特點包括:
兩個內存緩存加上 Native 緩存構成了三級緩存;
支持流式,可以類似網頁上模糊漸進式顯示圖片;
對多幀動畫圖片支持更好,如 Gif、WebP。
鑑於 Fresco 還沒發佈正式的 1.0 版本,同時一直沒太多時間熟悉 Fresco 源碼,後面對比不包括 Fresco,以後有時間再加入對比。
二 基本概念
在正式對比之前,先了解幾個圖片緩存的通用的概念:
- RequestManager:請求生成和管理模塊
- Engine:引擎部分, 負責創建任務(獲取數據),並調度執行
- GetDataInterface: 數據獲取接口,負責從各個數據源獲取數據,比如MemoryCache從內存緩存中獲取數據、DiskCache從本地緩存獲取數據,下載器從網絡獲取數據
- Displayer:資源(圖片)顯示器,用於顯示或者操作資源。比如ImageView,這幾個圖片緩存不僅僅支持ImageView,同時支持其他View以及虛擬的Displayer概念
- Processer:資源(圖片)處理器,負責處理資源,比如旋轉,壓縮,截取等。
以上概念的稱呼在不同的圖片緩存中可能有所不同,比如Displayer在ImageLoader中叫做ImageAware,在Picasso和Glide中叫做Target。
三 共同優點
- 使用簡單
都可以通過一句代碼來實現圖片的獲取和顯示。 - 可配置程度高
圖片緩存的下載器(重試機制)、解碼器、顯示器、處理器、內存緩存、本地緩存、線程池、緩存算法等大都可以輕鬆配置。 - 多級緩存
至少都有兩級緩存,提高圖片加載速度。 - 支持多種數據源
支持多種數據源:網絡、本地、資源、Assets等。 - 支持多種Displayer
不僅僅支持ImageView,同時也支持其他View和虛擬Disorder。 - 其他*
支持動畫,支持transform處理,獲取EXIF等
四 ImageLoader 設計及優點
- 總體設計及流程
上面是ImageLoader的總體設計圖。整個庫分爲ImageLoaderEngine,Cache及ImageDownLoad,ImageDecode,BitmapDisplayer,BitmapProcessor五大模塊,其中Cache分爲MemoryCache和DiskCache兩部分。 - ImageLoader優點
(1) 支持下載進度監聽
(2) 可以在View的滾動中暫停下載
通過PauseOnScrollListener接口可以在View滾動中暫停圖片加載
(3) 默認實現多種緩存算法
這幾種圖片緩存都可以配置緩存算法,不過ImageLoader默認實現了較多的緩存算法,如Size最大先刪除,使用最少先刪除,最近最少使用,先進先刪除,時間最長先刪除
(4)支持本地緩存文件名規則定義
五 Picasso設計及優點
總體設計及流程
上面是 Picasso 的總體設計圖。整個庫分爲 Dispatcher,RequestHandler 及 Downloader,PicassoDrawable 等模塊。
Dispatcher 負責分發和處理 Action,包括提交、暫停、繼續、取消、網絡狀態變化、重試等等。
簡單的講就是 Picasso 收到加載及顯示圖片的任務,創建 Request 並將它交給 Dispatcher,Dispatcher 分發任務到具體 RequestHandler,任務通過 MemoryCache 及 Handler(數據獲取接口) 獲取圖片,圖片獲取成功後通過 PicassoDrawable 顯示到 Target 中。
需要注意的是上面 Data 的 File system 部分,Picasso 沒有自定義本地緩存的接口,默認使用 http 的本地緩存,API 9 以上使用 okhttp,以下使用 Urlconnection,所以如果需要自定義本地緩存就需要重定義 Downloader。Picasso 優點
(1) 自帶統計監控功能
支持圖片緩存使用的監控,包括緩存命中率、已使用內存大小、節省的流量等。
(2) 支持優先級處理
每次任務調度前會選擇優先級高的任務,比如 App 頁面中 Banner 的優先級高於 Icon 時就很適用。
(3) 支持延遲到圖片尺寸計算完成加載
(4) 支持飛行模式、併發線程數根據網絡類型而變
手機切換到飛行模式或網絡類型變換時會自動調整線程池最大併發數,比如 wifi 最大併發爲 4, 4g 爲 3,3g 爲 2。
這裏 Picasso 根據網絡類型來決定最大併發數,而不是 CPU 核數。
(5) “無”本地緩存
無”本地緩存,不是說沒有本地緩存,而是 Picasso 自己沒有實現,交給了 Square 的另外一個網絡庫 okhttp 去實現,這樣的好處是可以通過請求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過期時間。
六、Glide 設計及優點
總體設計及流程
上面是 Glide 的總體設計圖。整個庫分爲 RequestManager(請求管理器),Engine(數據獲取引擎)、Fetcher(數據獲取器)、MemoryCache(內存緩存)、DiskLRUCache、Transformation(圖片處理)、Encoder(本地緩存存儲)、Registry(圖片類型及解析器配置)、Target(目標)等模塊。
簡單的講就是 Glide 收到加載及顯示資源的任務,創建 Request 並將它交給RequestManager,Request 啓動 Engine 去數據源獲取資源(通過 Fetcher ),獲取到後 Transformation 處理後交給 Target。
Glide 依賴於 DiskLRUCache、GifDecoder 等開源庫去完成本地緩存和 Gif 圖片解碼工作。Glide 優點
(1) 圖片緩存->媒體緩存
Glide 不僅是一個圖片緩存,它支持 Gif、WebP、縮略圖。甚至是 Video,所以更該當做一個媒體緩存。
(2) 支持優先級處理
(3) 與 Activity/Fragment 生命週期一致,支持 trimMemory
Glide 對每個 context 都保持一個 RequestManager,通過 FragmentTransaction 保持與 Activity/Fragment 生命週期一致,並且有對應的 trimMemory 接口實現可供調用。
(4) 支持 okhttp、Volley
Glide 默認通過 UrlConnection 獲取數據,可以配合 okhttp 或是 Volley 使用。實際 ImageLoader、Picasso 也都支持 okhttp、Volley。
(5) 內存友好
① Glide 的內存緩存有個 active 的設計
從內存緩存中取數據時,不像一般的實現用 get,而是用 remove,再將這個緩存數據放到一個 value 爲軟引用的 activeResources map 中,並計數引用數,在圖片加載完成後進行判斷,如果引用計數爲空則回收掉。
② 內存緩存更小圖片
Glide 以 url、viewwidth、viewheight、屏幕的分辨率等做爲聯合 key,將處理後的圖片緩存在內存緩存中,而不是原始圖片以節省大小
③ 與 Activity/Fragment 生命週期一致,支持 trimMemory
④ 圖片默認使用默認 RGB565 而不是 ARGB888
雖然清晰度差些,但圖片更小,也可配置到 ARGB_888。
其他:Glide 可以通過 signature 或不使用本地緩存支持 url 過期