Android fresco后处理器:java.lang.RuntimeException:画布:尝试使用回收的位图

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

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)

我构建了一个新类,并使它扩展了
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的客户视图。