Fresco使用之OOM问题记录

最近友盟上5.0以上系统报出很多OOM异常,看下日志看到facebook的时候就知道一定是Fresco使用不当导致了OOM。

1 java.lang.OutOfMemoryError: Failed to allocate a 2664012 byte allocation with 1460908 free bytes and 1426KB until OOM
2     at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
3     at android.graphics.Bitmap.nativeCreate(Native Method)
4     at android.graphics.Bitmap.createBitmap(Bitmap.java:825)
5     at android.graphics.Bitmap.createBitmap(Bitmap.java:802)
6     at android.graphics.Bitmap.createBitmap(Bitmap.java:769)
7     at com.facebook.imagepipeline.memory.BitmapPool.alloc(BitmapPool.java:51)
8     at com.facebook.imagepipeline.memory.BitmapPool.alloc(BitmapPool.java:26)
9     at com.facebook.imagepipeline.memory.BasePool.get(BasePool.java:255)

查资料原来5.0以上Fresco内存会持续增长,所以重新配置了Fresco

 1         //设置内存紧张时的应对措施
 2         MemoryTrimmableRegistry memoryTrimmableRegistry = NoOpMemoryTrimmableRegistry.getInstance();
 3         memoryTrimmableRegistry.registerMemoryTrimmable(new MemoryTrimmable() {
 4             @Override
 5             public void trim(MemoryTrimType trimType) {
 6                 final double suggestedTrimRatio = trimType.getSuggestedTrimRatio();
 7 
 8                 if (MemoryTrimType.OnCloseToDalvikHeapLimit.getSuggestedTrimRatio() == suggestedTrimRatio
 9                         || MemoryTrimType.OnSystemLowMemoryWhileAppInBackground.getSuggestedTrimRatio() == suggestedTrimRatio
10                         || MemoryTrimType.OnSystemLowMemoryWhileAppInForeground.getSuggestedTrimRatio() == suggestedTrimRatio) {
11                     //清空内存缓存
12                     ImagePipelineFactory.getInstance().getImagePipeline().clearMemoryCaches();
13                 }
14             }
15         });
16         //设置磁盘缓存
17         imagePipelineConfigBuilder.setMainDiskCacheConfig(DiskCacheConfig.newBuilder(this)
18                 .setBaseDirectoryPath(getExternalCacheDir())//设置磁盘缓存的路径
19                 .setBaseDirectoryName(getString(R.string.app_name))//设置磁盘缓存文件夹的名称
20                 .setMaxCacheSize(20 * ByteConstants.MB)//设置磁盘缓存的大小
21                 .build())
22                 .setDownsampleEnabled(true)
23                 .setMemoryTrimmableRegistry(memoryTrimmableRegistry);

  另外,加载一些大图需要根据View的尺寸缩放图片 (ResizeOptions)

 1     /**
 2      * 构建、获取ImageRequest
 3      * @param uri 加载路径
 4      * @param simpleDraweeView 加载的图片控件
 5      */
 6     public ImageRequest getImageRequest(Uri uri, SimpleDraweeView simpleDraweeView) {
 7         int width;
 8         int height;
 9         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
10             width = simpleDraweeView.getWidth();
11             height = simpleDraweeView.getHeight();
12         } else {
13             width = simpleDraweeView.getMaxWidth();
14             height = simpleDraweeView.getMaxHeight();
15         }
16 
17         //根据请求路径生成ImageRequest的构造者
18         ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(uri);
19         //调整解码图片的大小
20         if (width > 0 && height > 0) {
21             builder.setResizeOptions(new ResizeOptions(width, height));
22         }
23         //设置是否开启渐进式加载,仅支持JPEG图片
24         builder.setProgressiveRenderingEnabled(true);
25         return builder.build();
26     }

目前想到的从这两方面避免OOM,结果还是要看友盟的统计~

BY LiYing

原文地址:https://www.cnblogs.com/widgetbox/p/9543833.html