Android fresco后处理器:java.lang.RuntimeException:画布:尝试使用回收的位图
12-21 11:01:14.045:E/AndroidRuntime(6819): java.lang.RuntimeException:画布:尝试使用回收的位图 android.graphics。Bitmap@4180103 12-21 11:01:14.045: E/AndroidRuntime(6819):在 android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1084)12-21 11:01:14.045:E/AndroidRuntime(6819):在 android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:844)12-21 11:01:14.045:E/AndroidRuntime(6819):在 android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:490) 12-21 11:01:14.045:E/AndroidRuntime(6819):在 android.widget.ImageView.onDraw(ImageView.java:1037)12-21 11:01:14.045:E/AndroidRuntime(6819):在 android.view.view.draw(view.java:14465)12-21 11:01:14.045: E/AndroidRuntime(6819):在 android.view.view.getDisplayList(view.java:13362)12-21 11:01:14.045: E/AndroidRuntime(6819):在 android.view.view.getDisplayList(view.java:13404)12-21 11:01:14.045: E/AndroidRuntime(6819):位于android.view.view.draw(view.java:14182) 12-21 11:01:14.045:E/AndroidRuntime(6819):在 android.view.ViewGroup.drawChild(ViewGroup.java:3103)12-21 11:01:14.045:E/AndroidRuntime(6819):在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)12-21 11:01:14.045:E/AndroidRuntime(6819):在 android.widget.AbsListView.dispatchDraw(AbsListView.java:2458) 我构建了一个新类,并使它扩展了Android fresco后处理器:java.lang.RuntimeException:画布:尝试使用回收的位图,android,bitmap,fresco,Android,Bitmap,Fresco,12-21 11:01:14.045:E/AndroidRuntime(6819): java.lang.RuntimeException:画布:尝试使用回收的位图 android.graphics。Bitmap@4180103 12-21 11:01:14.045: E/AndroidRuntime(6819):在 android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1084)12-21 11:01:14.045:E/AndroidRun
BasePostprocessor
,我在其中什么都不做。但当它运行时,样本抛出上述异常;我只是使用imagepipeline
下载图像,而不是使用simpledraweview
com.facebook.imagepipeline.request.ImageRequestBuilder requestBuilder= com.facebook.imagepipeline.request.ImageRequestBuilder
.newBuilderWithSource(uri);
if (imageRequest.getTargetWidth() > 0 && imageRequest.getTargetHeight() > 0) {
requestBuilder.setResizeOptions(new com.facebook.imagepipeline.common.ResizeOptions(imageRequest
.getTargetWidth(), imageRequest.getTargetHeight()));
}
requestBuilder.setAutoRotateEnabled(true);
requestBuilder.setPostprocessor(new FPostProcessor(getImageConfig()));
public class FPostProcessor extends BasePostprocessor{
private FImageConfig mImageConfig;
public FPostProcessor(FImageConfig imageConfig){
mImageConfig = imageConfig;
}
/*
@Override
public CloseableReference<Bitmap> process(Bitmap sourceBitmap, PlatformBitmapFactory bitmapFactory) {
return super.process(sourceBitmap, bitmapFactory);
}*/
}
com.facebook.imagepipeline.request.ImageRequestBuilder requestBuilder=com.facebook.imagepipeline.request.ImageRequestBuilder
.newBuilderWithSource(uri);
if(imageRequest.getTargetWidth()>0&&imageRequest.getTargetWidth()>0){
requestBuilder.setResizeOptions(新建com.facebook.imagepipeline.common.ResizeOptions(imageRequest
.getTargetWidth(),imageRequest.getTargetWidth());
}
requestBuilder.setAutoRotateEnabled(true);
setPostprocessor(新的FPostProcessor(getImageConfig());
公共类FPostProcessor扩展了BasePostprocessor{
私有FImageConfig-mImageConfig;
公共FPostProcessor(FImageConfig imageConfig){
mImageConfig=imageConfig;
}
/*
@凌驾
公共可关闭引用进程(位图源位图、平台位图工厂位图工厂){
返回super.process(sourceBitmap、bitmapFactory);
}*/
}
我认为这与后处理器无关。如果您不是直接使用Dropee,而是使用imagepipeline,则需要非常小心处理图像。您应该阅读有关的文档
我怀疑您正在从管道中获取一个clsoeableference
,然后您只是从中取出位图,然后忘记了clsoeableference
。这样做是错误的。一旦clsoablereference
超出范围,它将很容易被垃圾收集,当GC发生时,底层位图可能会被回收。即使您使用直接提供位图的BaseBitmapDataSubscriber
,情况也是如此。这一点在本手册中也有详细介绍
使用后处理器而不是不使用后处理器的最可能原因是,在前一种情况下,位图缓存可能会使位图保持活动状态。对于后处理器,这不会发生,因为它没有启用缓存
换句话说,假设管道返回一个clsoablereference R1
,它用Bitmap B
包装CloseableImage I
。将有另一个CloseableReference R2
包装位图缓存中保存的相同CloseableImage I
,直到稍后缓存决定退出该图像。由于缓存和您都有对该图像的引用,因此其引用计数为2。即使您不遵守Fresco API,并且让CloseableReference R1
被垃圾收集,引用计数也只会下降到1,因为缓存中仍然有它。然而,你不应该依赖于此。这是没有后置处理器的
如果指定一个后处理器,则会发生一些稍有不同的情况。管道现在将使用位图B1
缓存原始可关闭图像I1
,但将使用位图B2
返回一个新的后处理可关闭图像I2
。由于您的后处理器未启用缓存,因此您将成为I2
引用的唯一持有者,而这一次如果让它被垃圾收集,您将留下一个可回收的位图,因为没有缓存来隐藏问题
需要明确的是,正确的解决方案不是启用后处理器缓存!正确的解决方案是正确处理管道返回的CloseableReference
,如文档中所述
如果没有提供您如何使用管道的实际代码,我无法确定,但很可能会发生这种情况。有没有解决此问题的方法?没有解决此问题的方法,我必须创建扩展DrawweeView的客户视图。