1. 程式人生 > >Glide與Fresco快取機制

Glide與Fresco快取機制

glide 

特點:
可以傳入activity、fragment,圖片的載入會和activity、fragment生命週期一致(比如onPause暫停、onResume重新載入,onDestory銷燬)
預設Bitmap格式RGB_565(比ARGB_8888小一半,點陣圖位數越高代表其可以儲存的顏色資訊越多,當然影象也就越逼真;RGB_565無法顯示圖片本身的透明度)
Glide載入的大小與imageview一致
可載入gif、WebP
可配置圖片動畫
體積500 KB

Google推薦

快取策略:
MemeryCache(LruCache最近最少使用演算法)、WeakReference(activeResources弱引用,每次GC會被回收)、DiskCache(磁碟快取)



載入過程:

正在使用中的圖片使用弱引用activeResources來進行快取,不在使用中的圖片使用LruCache來進行快取;

activeResources保證正在使用的圖片不被Lru演算法回收。

如果要使用圖片,首先從LruCache取出圖片,然後存到activeResources,圖片釋放的時候,再把圖片存到LruCache。這樣在使用LRU演算法的時候,正在使用的圖片在弱引用裡,就不會被回收。

硬碟快取,預設情況下在硬碟快取的就是轉換過後的圖片


快取處理鍵類:LruResourceCache、DiskCache



Fresco

特點:
SimpleDraweeView
影象的漸進式呈現

體積太大2~3M

也可載入gif、webP

5.0以下系統,把bitmap儲存到ashmen(匿名共享記憶體機制),不會啟動gc,使的介面不會因為gc而卡死,

Facebook主導



快取策略:

Fresco使用三級快取,已解碼記憶體快取;未解碼記憶體快取;磁碟快取


第一級快取就是儲存bitmap,直接存的就是bitmap物件,5.0 以下,這些位於ashmem,5.0以上,直接位於java的heap上
第二級快取儲存在記憶體,但是沒有解碼,使用時需要解碼,
第三級快取就是儲存在本地檔案,同樣檔案也未解碼,使用的時候要先解碼啦!

在5.0以下,GC將會顯著地引發介面卡頓。Fresco將圖片放到一個特別的記憶體區域。當然,在圖片不顯示的時候,佔用的記憶體會自動被釋放。這會使得APP更加流暢,減少因圖片記憶體佔用而引發的OOM。


載入圖片的流程:

查詢Bitmap快取中是否存在,存在則直接返回Bitmap直接使用,不存在則查詢未解碼圖片的快取,如果存在則進行Decode成Bitmap然後直接使用並加入Bitmap快取中,如果未解碼圖片快取中查詢不到,則進行硬碟快取的檢查,如有,則進行IO、轉化、解碼等一系列操作,最後成Bitmap供我們直接使用,並把未解碼(Encode)的圖片加入未解碼圖片快取,把Bitmap加入Bitmap快取中,如硬碟快取中沒有,則進行Network操作下載圖片,然後加入到各個快取中。


原始碼快取處理位置:

com.facebook.imagepipeline.core.ImagePipelineFactory初始化com.facebook.imagepipeline.core.ImagePipeline.java
ImagePipeline負責圖片的獲取和管理。圖片可以來自遠端伺服器,本地檔案,或者Content Provider,本地資源。壓縮後的檔案快取在本地儲存中,Bitmap資料快取在記憶體中。 
在5.0系統以下,Image Pipeline 使用 pinned purgeables 將Bitmap資料避開Java堆記憶體,存在ashmem中。這要求圖片不使用時,要顯式地釋放記憶體。 
SimpleDraweeView自動處理了這個釋放過程,所以沒有特殊情況,儘量使用SimpleDraweeView,在特殊的場合,如果有需要,也可以直接控制Image Pipeline。
我們可以通過imagepipeline判斷bitmap是否被快取,
ImagePipeline imagePipeline = Fresco.getImagePipeline();
imagePipeline.isInBitmapMemoryCache(Uri.parse(""));
imagePipeline.isInDiskCache(Uri.parse("xxx"));
刪除指定快取
Uri uri = Uri.parse("xxx");
imagePipeline.evictFromCache(uri);
imagePipeline.evictFromDiskCache(uri);