研究Fresco有段时间了,在内存使用上的确要比UIL的好挺多,但同时Fresco的使用也些许复杂,还有很多陷阱。
除了参看官方文档外,还需要注意一下问题:
一、配置
1、ImagePipelineConfig 要设置 setDownsampleEnabled(true),以打开对png等图片的自动缩放特性(缩放必须要设置ResizeOptions);
setResizeAndRotateEnabledForNetwork(),已对网络图也能进行resize处理,减少内存开销;
没有png等透明图片的显示要求,setBitmapsConfig设置为 RGB_565,减少内存开销;
2、如果有浏览本地图片的,并且一屏上显示多张(> 9),要将PoolFactory的flexByteArrayPoolParams的PoolParam的 maxSizeHardCap值设为 8MB以上。
默认是每个读取线程只有4MB的byte缓存池,但现在很多图片的文件大小都超过8MB,在同时加载多种图片时,容易出现缓存池大小不够,导致加载失败;
二、ImageRequest
1、加载文件路径不要直接直接使用 Uri.parse(),而要使用 Uri.fromFIle()。parse不会转义文件路径的unicode字符,导致加载失败;
2、ResizeOptions一定尽量要设置,并且是ImageView所显示的大小,这样可以尽可能的缩减加载的图像尺寸,节约内存;
3、加载到BitmapCache的图片都是带Resize的,如果两处加载同一个Uri,但ResizeOptions不同的话,那也是当做两张图片;
4、GIF图闪动:Fresco是不在内存中缓存GIF图的,每次显示都是重新解码,闪动可以设置ImageDecodeOption中的setDecodePreviewFrame(true),并不设置placeholder的图片;
三、缓存
1、直接获得内存缓存的Bitmap:
DataSource<CloseableReference<CloseableImage>> dataSource =
Fresco.getImagePipeline().fetchImageFromBitmapCache(request, null);
CloseableReference<CloseableImage> imageReference = null;
try {
imageReference = dataSource.getResult();
if (imageReference != null) {
CloseableImage image = imageReference.get();
// do something on this
}
} finally {
dataSource.close();
CloseableReference.closeSafely(imageReference);
}
四、预加载
使用预加载时,要预加载到内存并解码的,要注意ResizeOptions,和照片旋转照成的长宽对调。
1、预缓存到本地文件,但不加载到内存,自动忽略ResizeOptions:
Fresco.getImagePipeline()
.prefetchToDiskCache(imageRequest, null)
2、预加载到内存并解码(不需要立即拿到结果的),受ResizeOptions影响:
Fresco.getImagePipeline()
.prefetchToBitmapCache(imageRequest, null)
Fresco.getImagePipeline()
.fetchDecodedImage(imageRequest, null)
但要注意,返回的DataSource是不能直接拿到结果,需要subscribe DataSource
4、