Yelp app是如何使用Glide優化圖片加載的
原文:Glide – How Yelp’s Android App Loads Images
動態加載圖片是很多安卓應用的基礎。在Yelp(美國最大點評網站)中,圖片在把消費者與商家聯系起來的過程中至關重要。隨著網絡通信和硬件水平的越發強大,消費者對于圖片數量和圖片質量的期望日益增長。圖片可以輕易的成為內存和網絡流量的消耗大戶,處理圖片數據的下載和管理成為了一個讓人望而卻步的任務。我們探索了幾種處理這個問題的解決辦法,最終認為Glide在性能,使用方便性,穩定性上達到了相當好的平衡。
Glide最簡單的使用案例就是從遠程服務器或者本地文件系統加載圖片,把它們放在磁盤與內存緩存中,然后加載到view上。它可以用在全市圖片的app中,Glide為包含圖片的滾動列表做了盡可能流暢的優化。
對象池
Glide原理的核心是為bitmap維護一個對象池。對象池的主要目的是通過減少大對象的分配以重用來提高性能(至于對象池的概覽,可以查看 這個Android performance pattern 視頻)。
Dalvik和ART虛擬機都沒有使用compacting garbage collector,compacting garbage collector是一種模式,這種模式中GC會遍歷堆,同時把活躍對象移到相鄰內存區域,讓更大的內存塊可以用在后續的分配中。因為安卓沒有這種模式,就可能會出現被分配的對象分散在各處,對象之間只有很小的內存可用。如果應用試圖分配一個大于鄰近的閑置內存塊空間的對象,就會導致OutOfMemoryError,然后崩潰,即使總的空余內存空間大于對象的大小。
使用對象池還可以幫助提高滾動的性能,因為重用bitmap意味著更少的對象被創建與回收。垃圾回收會導致“停止一切(Stop The World)”事件,這個事件指的是回收器執行期間,所有線程(包括UI線程)都會暫停。這個時候,圖像幀無法被渲染同時UI可能會停滯,這在滾動期間尤其明顯。
Glide的使用
Glide使用起來很簡單,而且不需要任何特別的配置就自動包含了bitmap pooling 。
DrawableRequestBuilder requestBuilder = Glide.with(context).load(imageUrl); requestBuilder.into(imageView);
這就是加載一張圖片的全部要求。就像安卓中的很多地方一樣,with() 方法中的context到底是哪種類型是不清楚的。有一點很重要需要記住,就是傳入的context類型影響到Glide加載圖片的優化程度,Glide可以監視activity的生命周期,在activity銷毀的時候自動取消等待中的請求。但是如果你使用Application context,你就失去了這種優化效果。
譯者注:其實以上的代碼是一種比較規范的寫法,我們更熟悉的寫法是:
Glide.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg); 優化特性
類似的是,如果相關的item已經滾出了屏幕的范圍,Glide會自動取消列表中的懸著的圖片請求 。因為絕大多數開發者都會在adapter中利用view的回收,Glide做到這點是通過在ImageView上設置一個tag,在加載另外一張圖片之前檢查這個tag,如果存在就取消第一次請求。
Glide提供了幾個讓你感覺圖片加載速度變快的特性。第一個就是在圖片顯示在屏幕上之前就預先取出圖片。它提供了一個ListPreloader類, 它被應該事先取出的item數目實例化。然后通過setOnScrollListener(OnScrollListener).被傳遞給ListView。你想在ListView之外也能預先取出圖片嗎?沒問題,使用前面的builder對象就可以了,只需調用builder.downloadOnly()。
downloadOnly見:https://github.com/bumptech/glide/wiki/Loading-and-Caching-on-Background-Threads 。
我們發現了Glide提供的可以大大提高性能,穩定性的功能,以及安卓圖片加載領域的一些設計哲學。這些特性和優化確實可以很好的將圖片加載的體驗變成一種享受。
來自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0728/3228.html