引言
最近圈子開發工作比較重再加上寒冬已至,所以停了兩個月沒寫,手有點生,好吧,這都是借口,我承認~( ̄▽ ̄~),下面回歸正題。
一般地在使用Fresco圖片的時候,無需擔心圖片大小的問題,因為
通常服務器返回的圖片大小不會非常誇張,但當你需要從手機本地圖庫中加載多圖的時候,例如相冊選擇器,這時你就不得不考慮圖片的大小問題了,因為由於android系統分配給每個app的內存是有限的,而用戶的本地圖片大小是無法控制的,所以當同時加載多張大圖時就很容易造成OOM的問題。
解決OOM
Fresco支持對圖片的裁減,為了防止在加載本地圖片出現OOM,我們可以在加載圖片時直接配置好裁剪的參數,這樣就可以基本防止了app出現OOM的情況。示例代碼如下,很簡單:
ResizeOptions options = new ResizeOptions(width, height);
public static void displayImage(File imageFile , SimpleDraweeView imageView, ResizeOptions options) {
ImageRequest request = ImageRequestBuilder
.newBuilderWithSource(Uri.fromFile(image))
.setResizeOptions(options)
.build();
... ...
}
但是問題到這里並沒有完全解決!
使用ResizeOptions后仍然會OOM
有時你會發現當即使用了ResizeOptions后,特別是加載本地多圖時仍然會發生OOM,或加載頁面會異常的卡頓忙,或者有的圖片加載不出來,黑屏。是ResizeOptions的bug嗎?答案肯定不是,造成的原因就在於你的使用姿勢不正確!
-
不正確姿勢1:
ResizeOptions的參數設置有問題。
這里的參數問題指的是你設置的裁剪寬高值仍然太大了,並沒有很好的適應的你需求。例如當一個頁面類似於圖片相冊顯示多張本地圖片時,如果你直接根據屏幕的寬度等分(如: 屏寬/3)的值來設置參數,就有可能出現圖片無法加載的情況,因為本地圖片可能十幾M甚至更大,在這樣的情況下直接以分辨率進行裁剪,在某些性能較差的手機上圖片就可能顯示不出來。 -
不爭取姿勢2:
ResizeOptions只支持JPG格式的圖片。
這一點Fresco在官方文檔上有非常明確的說明,如圖:
附上官方說明鏈接 ResizeOptions這個問題一般只有在加載本地圖片時在容易遇到,因為一般應用從服務器接受的圖片都是JPG格式的,但手機本地圖片就非常多了,如最常見的PNG等都是不支持裁剪的,所以當你信心滿滿的設置好ResizeOptions后發現加載大圖時手機仍然OOM了。(這就是吃了不仔細看官方文檔的虧!當時被坑了好久才發現-。-)
解決ResizeOptions支持格式的問題
關於這個問題其實在github上已經有很多提出了,只不過很多人並知道是ResizeOptions支持格式的問題,只是在描述他們出現的問題。在這里非常感謝tyronen,他在issues上歸類了這一類問題,並非常明確的指出了問題所在。
在fresco最新的版本上增加了一個新的功能:Downsampling,它處理圖片的速度比常規的裁剪更快,並且同時支持PNG,JPG以及WEP格式的圖片,非常強大。其使用方式也很簡單,在配置ResizeOptions方法的基礎上,再把ImagePipelineConfig中的Downsampling開關打開即可,代碼如下:
ImagePipelineConfig.newBuilder(context). .setDownsampleEnabled(true).build();
但不得不提醒的是,在目前最新的0.8.1上該功能仍為試驗功能,所以當你決定在項目上使用該功能時一定要做好相關的風險預估。
最后附上官方文檔的具體說明 Downsampling
結語
開源庫的力量非常強大,但並不是完美的,我們在使用時千萬不能無腦復制黏貼,要留心說明文檔,以及適當閱讀相關源碼,這樣才能做到更好的使用開源庫和提升自己,避免很多不必要的彎路。
作者:XycZero
查看原文:http://www.xyczero.com/blog/article/28/.