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