Glide不僅是我們常用的圖片加載框架也是面試中的高頻問題,但是我發現許多作業多年的小伙伴任然只是停留在使用階段,
今天我想要站在面試者的角度,和大家聊一聊Glide,我希望當大家看完這篇文章后,當面試官問你為什么使用Glide時,我希望你不要像下面一樣回答,
我進入專案小組就是使用的Glide圖片加載框架,它能夠滿足我們日常的業務需求,所以就一直使用的Glide,
為什么使用Glide?
面試官:看你簡歷上說熟練使用Glide,能夠說一說為什么專案上圖片加載框架使用的是Glide而不是其它呢?
1.使用方便,API簡潔,with、load、into 三步就可以加載圖片
2.生命周期自動系結,根據系結的Activity或Fragment生命周期管理圖片請求
3.支持多級配置:應用、單獨頁面(Activity/Fragment)、單個請求進行獨立配置,
4.高效快取策略,兩級記憶體 ,兩級檔案,
5.支持多種圖片格式(Gif、WebP、Video), 擴展靈活
Glide加載流程
Glide的加載程序大致如下,Glide#with獲取與生命周期系結的RequestManager,RequestManager通過load獲取對應的RequestBuilder,根據RequestBuilder構建對應的Request,Target 將Request,Target 交給RequestManager進行統一管理,呼叫RequestManager#track開始進行圖片請求,request通過Engine分別嘗試從活動快取、Lru快取、檔案快取中加載圖片,當以上的快取中都不存在對應的圖片后,會從網路中獲取,而網路獲取大致可以分成,ModelLoader模型匹配,DataFetcher資料獲取,然后經歷解碼、圖片變換、轉換,如果能夠進行快取原始資料,還會將解碼的資料進行編碼快取到檔案,
Glide生命周期管理
Glide通過給Fragment/Activity插入一個不可見的Fragment,通過監聽該Fragment的生命周期,來實作對應的請求管理,但是需要注意的是,如果在Fragment中使用Activity,在圖片的請求程序中Fragment被銷毀,但是請求并沒有結束,會造成記憶體泄漏,
Glide RequestOptions請求引數配置
GlideReuqestOptions引數配置分為三級,第一級作用于Glide ,在RequestManger的構造方法通過GlideContext獲取 進行配置處理,第二即作用于RequestManger如果我們要針對某個
RequestManger進行配置處理,那么需要使用RequestManger#applyDefaultRequestOptions來對默認的配置進行更新,第三級作用于RequestBuilder,通過它的apply方法為每一個請求的配置進行更新,
Glide快取管理
Glide快取分為,記憶體快取,檔案快取,網路快取,其中記憶體快取又分為活動資源快取,Lru快取,檔案快取分為資源快取和原始資料快取,
記憶體快取
活動資源快取將每一個正在使用的圖片加入活動資源快取,每增加一個使用物件參考計數器加一,否則減一,
Lru快取是按照最近最少使用的原則來對圖片記憶體快取進行維護,當Lru快取滿了的時候,優先移除訪問時間最久的那個,
活動資源快取以較小的代價,維護當前在記憶體中使用的圖片資源,減輕Lru快取的壓力,提高快取效率,
檔案快取
資源檔案快取是根據當前所需要的資源型別,圖片大小等特定資訊進行的快取,當從資源快取中獲取資料的時候,不需要進行解碼操作,獲取的資料可以直接進行使用,
原始資料是根據網路加載的資料,直接進行快取,使用的時候還需要重新進行解碼,轉換的流程,
記憶體管理
Glide的記憶體管理有兩塊,一、OOM的防治;二、記憶體抖動,
OOM
圖片加載非常重要的一點就是OOM的防治,Glide通過圖片采樣,弱參考、生命周期系結等方式,減小加載到記憶體的的圖片大小,及時清除不需要在使用物件的參考,從而減小OOM的概率,
圖片的加載
Glide針對較大的圖片,會根據當前ui的顯示大小與實際大小的比例,進行采樣計算從而減小圖片在記憶體中的占用,一般而言
圖片的大小 = 圖片寬 X 圖片高 X 每個像素占用的位元組數,
對于資源檔案夾下的圖片:
圖片的高 = 原圖高 X (設備的 dpi / 目錄對應的 dpi )
圖片的寬 = 原圖寬 X (設備的 dpi / 目錄對應的 dpi )
onlowMemory/onTrimMemory
Glide通過實作ComponentCallbacks2并將其注冊進Applition, 當記憶體過低的時候會呼叫onlowMemory,在onlowMemory 中Glide會將一些快取的記憶體進行清除,方便進行記憶體回收,當onTrimMemory被呼叫的時候,如果level是系統資源緊張,Glide會將Lru快取和BitMap重用池相關的內容進行回收,如果是其他的原因呼叫onTrimMemory,Glide會將快取的內容減小到配置快取最大內容的1/2,
借助弱參考
Glide通過RequestManager管理圖片請求,而RequestManager內部是通過RequestTracker和TargetTracker來完成的,他們持有的方式都是弱參考,
記憶體抖動的處理.
Glide通過重用池技術,將一些常用的對應進行池話,比如圖片加載相關的EngineJob DecodeJob等一下需要大量重復使用創建的物件,通過物件重用池進行物件重用,
BitmapPool對Bitmap進行物件重用,在對圖片進行解碼的的時候通過設定BitmapFactory.Options#inBitmap來達到記憶體重用的目的,
在 Android 3.0(API 級別 11)開始,系統引入了 BitmapFactory.Options.inBitmap 欄位,如果設定了此選項,那么采用 Options 物件的解碼方法會在生成目標 Bitmap 時嘗試復用 inBitmap,這意味著 inBitmap 的記憶體得到了重復使用,從而提高了性能,同時移除了記憶體分配和取消分配,不過 inBitmap 的使用方式存在某些限制,在 Android 4.4(API 級別 19)之前系統僅支持復用大小相同的位圖,4.4 之后只要 inBitmap 的大小比目標 Bitmap 大即可
串列頁圖片加載資料錯亂
由于RecyclerView、ListView的View復用機制,可能出現第一個item的圖片顯示在第10個上,這個明顯是錯誤的,Glide通過給Target#setRequest,將Target與Request關聯,針對View型別的Target,setRequest的實質是給View設定tag,通過tag保存request,當下一個持有相同View的Target到來的時候,也可以取出原來的request,并將其取消,但是針對非View型別的target,如果要使用這個特性,我們需要提供原來的在使用的target,而不是像View一樣重新創建一個新的物件,
Glide中的執行緒&執行緒池
關于Glide中的執行緒執行緒池,準備說兩個方面
- 圖片加載回呼
- Glide的執行緒池配置
圖片加載回呼
Glide有兩種圖片加載方式into和submit 通過into加載的圖片會通過Executors#MAIN_THREAD_EXECUTOR回呼到主執行緒,
而通過submit的進行回呼的會通過Executors#DIRECT_EXECUTOR在當前執行緒進行處理,
Glide執行緒池配置
執行緒作為cpu調度的最小單元,每一次的創建和回收都會有較大的消耗,通過使用執行緒池可以
- 降低資源消耗:通過重復利用已創建的執行緒降低執行緒創建和銷毀造成的消耗,
- 提高回應速度:當任務到達時,可以不需要等待執行緒創建就能立即執行,
- 提高執行緒的可管理性:執行緒是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用執行緒池可以進行統一的分配,監控和調優,
- 有效的控制并發數
Glide中提供了四種執行緒池配置,
- DiskCacheExecutor 該執行緒池只有一個核心執行緒,沒有非核心執行緒,所有任務在執行緒池中串行執行,在Glide中常用與從檔案中加載圖片,
- SourceExecutor 該執行緒也只有核心執行緒沒有非核心執行緒,與DiskCacheExecutor 的不同之處在于核心執行緒的數量根據CPU的核數來決定,如果cpu核心數超過4則核心執行緒數為4 如果Cpu核心數小于4那么使用Cpu核心數作為核心執行緒數量,在Glide中長用來從網路中加載圖片,
- UnlimitedSourceExecutor 沒有核心執行緒,非核心執行緒數量無限大,這種型別的執行緒池常用于執行量大而快速結束的任務,在所有任務結束,在所有任務結束后幾乎不消耗資源,
- AnimationExecutor 沒有核心執行緒,非核心執行緒數量根據Cpu核心數來決定,當Cpu核心數大于等4時 非核心執行緒數為2,否則為1,
Glide如何加載不同型別的資源
Glide通過RequestManager#as方法確定當前請求Target最終需要的資源型別,通過load方法確定需要加載的model資源型別,資源的加載程序經歷ModelLoader的model加載匹配,解碼器解碼,轉碼器的轉換,這幾個程序構建成一個LoadPath ,而每一個LoadPath 又包含很多的DecodePath,DecodePath的主要作用是將ModelLoader加載出來的資料進行解碼,轉換,
Glide會遍歷所有可能決議出對應資料的LoadPath 直到資料正真決議成功,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/382031.html
標籤:其他
上一篇:Android 最新狀態欄處理
