首页 文章

fresco后处理器:java.lang.RuntimeException:Canvas:尝试使用循环位图

提问于
浏览
3

12-21 11:01:14.045:E / AndroidRuntime(6819):java.lang.RuntimeException:Canvas:尝试使用循环位图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):at 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):at android.widget.ImageView.onDraw(ImageView.java:1037)12-21 11:01:14.045:E / AndroidRuntime(6819):at 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):at android.view.View.getDisplayList (View.java:13404)12-21 11:01:14.045:E / AndroidRuntime(6819):at 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):at 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 下载图片,不要使用 simpledraweeview .

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);
}*/
}

1 回答

  • 0

    我不认为这与后处理器有任何关系 . 如果您不使用Drawee,但直接使用imagepipeline,则需要非常小心处理图像 . 您应该阅读有关how to use the imagepipeline directly的文档 .

    我怀疑你从管道中得到一个 ClsoeableReference<CloseableImage> ,然后你只需要取出Bitmap而忘记 ClsoeableReference . 这是一件错误的事情 . 一旦 ClsoeableReference 超出范围,它就会变得容易进行垃圾收集,并且当GC发生时,底层位图可能会被回收 . 即使您使用直接提供Bitmap的 BaseBitmapDataSubscriber 也是如此 . documentation中也详细介绍了这一点 .

    最有可能的原因是您使用后处理器而不是没有后处理器,因为在前一种情况下,位图缓存可能会使您的位图保持活动状态 . 使用后处理器,这不会发生,因为它没有启用缓存 .

    换句话说,管道返回 ClsoeableReference<CloseableImage> R1 ,用 Bitmap B 包装 CloseableImage I . 将会有另一个 CloseableReference R2 包装保存在位图缓存中的相同 CloseableImage I ,直到稍后缓存决定驱逐该图像 . 由于缓存和你都有对该图像的引用,它_1140881_ t服从Fresco API而你让 CloseableReference R1 得到垃圾收集,引用计数只会降到1,因为缓存仍然在内存中 . 但是,你不应该依赖它 . 那是 without 后处理器 .

    如果指定后处理器,则会发生稍微不同的事情 . 现在,管道将使用 Bitmap B1 缓存原始 CloseableImage I1 ,但将返回带有 Bitmap B2new postprocessed CloseableImage I2 . 由于您的后处理器没有启用缓存,因此您将成为对 I2 的引用的 only 持有者,这次如果您让它被垃圾收集,您将留下一个回收的位图,因为没有缓存来隐藏问题 .

    为了清楚起见,正确的解决方案是不启用后处理器缓存!正确的解决方案是正确处理管道返回的 CloseableReference ,如文档中所述 .

    如果没有提供你如何使用管道的实际代码,我无法确定,但这很可能发生了什么 .

相关问题