最近友盟上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