最近友盟上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,结果还是要看友盟的统计~

LiYing