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 回答
我不认为这与后处理器有任何关系 . 如果您不使用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 B2
的 new postprocessedCloseableImage I2
. 由于您的后处理器没有启用缓存,因此您将成为对I2
的引用的 only 持有者,这次如果您让它被垃圾收集,您将留下一个回收的位图,因为没有缓存来隐藏问题 .为了清楚起见,正确的解决方案是不启用后处理器缓存!正确的解决方案是正确处理管道返回的
CloseableReference
,如文档中所述 .如果没有提供你如何使用管道的实际代码,我无法确定,但这很可能发生了什么 .