圖片加載庫對比

圖片加載庫原理

爲什麼要使用三級緩存

  • 如今的 Android App 經常會需要網絡交互,通過網絡獲取圖片是再正常不過的事了
  • 假如每次啓動的時候都從網絡拉取圖片的話,勢必會消耗很多流量。在當前的狀況下,對於非wifi用戶來說,流量還是很貴的,一個很耗流量的應用,其用戶數量級肯定要受到影響
  • 特別是,當我們想要重複瀏覽一些圖片時,如果每一次瀏覽都需要通過網絡獲取,流量的浪費可想而知
  • 所以提出三級緩存策略,通過網絡、本地、內存三級緩存圖片,來減少不必要的網絡交互,避免浪費流量

什麼是三級緩存

  • 網絡緩存, 不優先加載, 速度慢,浪費流量
  • 本地緩存, 次優先加載, 速度快
  • 內存緩存, 優先加載, 速度最快

三級緩存原理

  • 首次加載 Android App 時,肯定要通過網絡交互來獲取圖片,之後我們可以將圖片保存至本地SD卡和內存中
  • 之後運行 App 時,優先訪問內存中的圖片緩存,若內存中沒有,則加載本地SD卡中的圖片
  • 總之,只在初次訪問新內容時,才通過網絡獲取圖片資源

圖片加載庫簡介

通過對比來介紹三大圖片加載庫(由於ImageLoader已經停止更新,故不做介紹):

名稱 Picasso Glide Fresco
作者 Square Google員工開源項目 Facebook

Picasso

功能和優點

  • 支持統計監控功能,包括緩存命中率、已使用內存大小、節省的流量等。
  • 支持優先級操作
  • 支持延遲到圖片尺寸計算完成加載
  • 根據網絡狀態自動切換併發線程數量,包括飛行模式

主要缺點

  • 沒有本地緩存,Picasso的設計上是將緩存交給了Square的另一個庫OkHttp,這樣的好處是可以通過請求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過期時間。
  • 內存佔用量相對較大,甚至容易出現內存泄露,參見這個測試

Glide

功能和優點

Glide總體設計圖

  • 支持多種媒體格式,包括Gif、WebP、縮略圖,甚至Video。所以Glide實際上可以看作一個媒體緩存
  • 支持優先級處理
  • Glide的設計注重平滑的滑動,所以即使在列表中使用也非常流暢
  • 支持圖片的轉碼(toBytes()transcode())和淡入淡出(crossFade)效果
  • 支持同步和異步加載
  • 內置生命週期管理,支持Context(Activity、Fragment)調用,並提供了可供擴展的trimMemory接口。
  • 支持網絡連接配置,默認使用UrlConnection,也可以配合OkHttp或者Volley使用。
  • 內存友好,包括自動清理內存緩存、緩存圖片尺寸、默認使用RGB_565等。以至於Google官方把使用Glide作爲App性能優化的典範,視頻戳這裏:Performance optimisations for android applications - Part 7 Using Glide image loading framework

主要缺點

  • 相對於Square的Picasso和Facebook的Fresco,Glide雖然是由Google員工開發和維護並在Google產品中有一定的應用,但並不是Google的官方加載庫。

Fresco

功能和優點

Fresco的設計和前面幾個庫都大不相同:它自己定義了一個顯示圖片的View(稱爲Drawee)。大部分功能都可以使用SimpleDraweeView來實現,並且幾乎所有可配置的屬性都支持XML配置。

  • 三級緩存(內存2級,文件1級)
  • 支持漸進式JPEG圖片
  • 支持Gif和WebP格式
  • 支持圓角、Overlay、placeHolder、failure等多種場景顯示
  • 支持圖片預處理(Postprocessor)、縮放和旋轉
  • 對於5.0版本以下的設備,Fresco有專門的native內存管理優化
  • 支持完全自定義的網絡層

主要缺點

  • SimpleDraweeView繼承自ImageView,但是如果應用程序調用了原生ImageView的方法,例如setImageBackground,會使得內部的DraweeHierachy完全丟失。而且在Fresco的中文文檔中明確說明後續版本這個控件可能直接從View類派生。所以在使用DraweeView時不能使用ImageView的任何API,也不能依賴於其繼承自ImageView甚至View的繼承樹

  • 不支持wrap_content屬性SimpleDraweeView必須顯式指定寬度和高度。

  • ScrollView不兼容。使用RecyclerViewListView,或GridView沒問題,但是使用ScrollView會使得Fresco的內存管理失效,極大增加OOM的風險。其他Fresco使用陷阱可以看這裏:Fresco-cn.org

  • 據說大列表中滑動會造成UI卡頓……警察叔叔,是他說的

  • 類庫依賴過於龐大。超過14K的方法和2M+的jar包依賴,使得Fresco在需要避免65k方法數的場景變得非常危險。

    在0.10.0版本中,官方已經在嘗試解決這個問題,確實有所緩解,但遠沒到解決這個問題的程度。

  • 切換圖片加載庫會很困難。由於大部分功能依賴於SimpleDraweeView,因此和使用其他的加載庫的佈局文件會有所區別,導致老項目難以遷移;同時一開始就使用Fresco的新項目,以後無論出於什麼原因需要換庫,同樣會很麻煩。

Glide和Picasso的對比

基礎

Glide 和 Picasso 非常相似,Glide 加載圖片的方式和 Picasso 如出一轍。
雖然兩者看起來一樣,但 Glide 更易用,因爲 Glide 的 with 方法不光接受 Context,還接受 Activity 和 Fragment,Context 會自動的從他們獲取,同時將 Activity/Fragment 作爲 with()參數的好處是:圖片加載會和 Activity/Fragment 的生命週期保持一致,比如 Paused 狀態在暫停加載,在 Resumed 的時候又自動重新加載。

圖像和內存

類型 Glide Picasso
默認格式 RGB-565 ARGB-8888
內存開銷
圖片細節 迅速 平滑
磁盤緩存 與ImageView尺寸大小一致,調整尺寸後需要重新加載,可代碼配置爲緩存全尺寸 全尺寸
特性 媒體緩存 僅支持圖片緩存

結論

  1. 如果預見項目中會有很多圓角或漸進式JPEG等需求,可以使用Fresco;
  2. 如果是老項目已經使用了UIL或者Picasso,且依賴較多不容易修改,則可以繼續使用;
  3. 如果還在糾結如何避免65K方法數,推薦使用Glide代替Fresco 因爲Glide比後者實在輕巧了太多
  4. 如果是老項目需要換加載庫,推薦使用Glide而不是Fresco, 降低遷移工作量;
  5. 如果是新項目,不推薦使用已經停止維護的UIL,也不推薦Picasso,推薦使用Glide;
  6. 如果你是Google粉……不用推薦了,Glide趕緊用!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章