glide圖片載入原理

bok發表於2018-08-07

glide圖片載入原理

參考 連結一

簡介的簡介

第一步:Glide.with(context) 在傳入為fragment或者Activity的時候新增一個沒有view的fragment來監控生命週期

第二步:load(url)生成RequestBuilder

第三步:into(ImageView) 開始工作 先在DiskCacheService 中查詢 :先找LRU cache 再找activeCache(會刪除LRUCache中的引用放到activeCache中)如果找不到再在SourceService中查詢(大部分是下載)下載完成之後先根據imageview的寬高獲取部分圖片內容,再在移除之後放在lruCache中

簡介

Glide庫的資源複用:
  • Android的記憶體申請幾乎都在new的時候發生,而new較大物件(比如Bitmap時),更加容易觸發GC_FOR_ALLOW。所以Glide儘量的複用資源來防止不必要的GC_FOR_ALLOC引起卡頓。
  • 最顯著的記憶體複用就是記憶體LruResourceCache(第一次從網路或者磁碟上讀取到Resource時,並不會儲存到LruCache當中,當Resource被release時,也就是View不在需要此Resource時,才會進入LruCache當中)
  • 還有BitmapPool(Glide會盡量用圖片池來獲取到可以複用的圖片,獲取不到才會new,而當LruCache觸發Evicted時會把從LruCache中淘汰下來的Bitmap回收,也會把transform時用到的中間Bitmap加以複用及回收)
Glide庫圖片池:
  • 4.4以前是Bitmap複用必須長寬相等才可以複用
  • 4.4及以後是Size>=所需就可以複用,只不過需要呼叫reconfigure來調整尺寸
  • Glide用AttributeStategy和SizeStrategy來實現兩種策略
  • 圖片池在收到傳來的Bitmap之後,通過長寬或者Size來從KeyPool中獲取Key(物件複用到了極致,連Key都用到了Pool),然後再每個Key對應一個雙向連結串列結構來儲存。每個Key下可能有很多個待用Bitmap
  • 取出後要減少圖片池中記錄的當前Size等,並對Bitmap進行eraseColor(Color.TRANSPAENT)操作確保可用
Glide載入發起流程:
  1. Glide.with(context)建立RequestManager
    • RequestManager負責管理當前context的所有Request
    • Context可以傳Fragment、Activity或者其他Context,當傳Fragment、Activity時,當前頁面對應的Activity的生命週期可以被RequestManager監控到,從而可以控制Request的pause、resume、clear。這其中採用的監控方法就是在當前activity中新增一個沒有view的fragment,這樣在activity發生onStart onStop onDestroy的時候,會觸發此fragment的onStart onStop onDestroy。
    • RequestManager用來跟蹤眾多當前頁面的Request的是RequestTracker類,用弱引用來儲存執行中的Request,用強引用來儲存暫停需要恢復的Request。
  2. Glide.with(context).load(url)建立需要的Request
    • 通常是DrawableTypeRequest,後面可以新增transform、fitCenter、animate、placeholder、error、override、skipMemoryCache、signature等等
    • 如果需要進行Resource的轉化比如轉化為Byte陣列等需要,可以加asBitmap來更改為BitmapTypeRequest
    • Request是Glide載入圖片的執行單位
  3. Glide.with(context).load(url).into(imageview)
    • 在Request的into方法中會呼叫Request的begin方法開始執行
    • 在正式生成EngineJob放入Engine中執行之前,如果並沒有事先呼叫override(width, height)來指定所需要寬高,Glide則會嘗試去獲取imageview的寬和高,如果當前imageview並沒有初始化完畢取不到高寬,Glide會通過view的ViewTreeObserver來等View初始化完畢之後再獲取寬高再進行下一步
Glide載入資源:
  • GlideBuilder在初始化Glide時,會生成一個執行機Engine
  • Engine中包含LruCache快取及一個當前正在使用的active資源Cache(弱引用)
  • activeCache輔助LruCache,當Resource從LruCache中取出使用時,會從LruCache中remove並進入activeCache當中
  • Cache優先順序LruCache>activeCache
  • Engine在初始化時要傳入兩個ExecutorService,即會有兩個執行緒池,一個用來從DiskCache獲取resource,另一個用來從Source中獲取(通常是下載)
  • 執行緒的封裝單位是EngineJob,有兩個順序狀態,先是CacheState,在此狀態先進入DiskCacheService中執行獲取,如果沒找到則進入SourceState,進到SourceService中執行下載

相關文章