android bitmap回收,bitmap被回收导致的一个bug

在ListView的getView方法中使用Fresco加载图片并显示为SpannableString时,遇到Bitmap回收导致的运行时异常。当滑动大量页面后,部分TextView中的Bitmap被回收,触发Canvas尝试使用已回收的Bitmap。解决办法是正确管理和释放Bitmap资源,避免在滚动过程中回收正在使用的图片。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一个listview的getview方法中,有如下的代码:

ImageRequest imageRequest = ImageRequestBuilder

.newBuilderWithSource(Uri.parse(tuanItem.imgUrl))

.build();

ImagePipeline imagePipeline = Fresco.getImagePipeline();

DataSource dataSource = imagePipeline.fetchDecodedImage(imageRequest, this);

DataSubscriber dataSubscriber = new BaseDataSubscriber>() {

@Override

public void onNewResultImpl(DataSource> dataSource) {

if (!dataSource.isFinished()) {

return;

}

CloseableReference imageReference = dataSource.getResult();

if (imageReference != null) {

try {

CloseableBitmap closeableBitmap = (CloseableBitmap)imageReference.clone().get();

Bitmap loadedImage = closeableBitmap.getUnderlyingBitmap();

if (loadedImage == null)

return;

Drawable drawable = new BitmapDrawable(loadedImage);

drawable.setBounds(0, 0, Utils.dip2px(mActivity, (float) 40),

Utils.dip2px(mActivity, (float) 15));

SpannableString spannableString = new SpannableString(" " + tuanItem.mTitle);

spannableString.setSpan(new ImageSpan(drawable), 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

holder.title.setText(spannableString);

} finally {

imageReference.close();

}

}

}

@Override

public void onFailureImpl(DataSource dataSource) {

holder.title.setText(tuanItem.mTitle);

}

};

dataSource.subscribe(dataSubscriber, CallerThreadExecutor.getInstance());

如上面代码所示,我把一个通过dataSubscriber获取到的bitmap对象以SpannableString的方式放入一个TextView中。当滑动了大量页面之后,部分textview中的bitmap被回收,导致了如下的bug:

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@433bbad8

at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1084)

at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:844)

at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:493)

at android.text.style.DynamicDrawableSpan.draw(DynamicDrawableSpan.java:107)

at android.text.TextLine.handleReplacement(TextLine.java:854)

at android.text.TextLine.handleRun(TextLine.java:937)

at android.text.TextLine.drawRun(TextLine.java:395)

at android.text.TextLine.draw(TextLine.java:193)

at android.text.Layout.drawText(Layout.java:348)

at android.text.Layout.draw(Layout.java:205)

at android.widget.TextView.onDraw(TextView.java:5172)

at android.view.View.draw(View.java:14476)

at android.view.View.getDisplayList(View.java:13373)

at android.view.View.getDisplayList(View.java:13415)

at android.view.View.draw(View.java:14193)

at android.view.ViewGroup.drawChild(ViewGroup.java:3103)

at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)

at android.view.View.draw(View.java:14479)

at android.view.View.getDisplayList(View.java:13373)

at android.view.View.getDisplayList(View.java:13415)

at android.view.View.draw(View.java:14193)

at android.view.ViewGroup.drawChild(ViewGroup.java:3103)

at android.widget.ListView.drawChild(ListView.java:3363)

at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)

at android.widget.AbsListView.dispatchDraw(AbsListView.java:2477)

at android.widget.ListView.dispatchDraw(ListView.java:3358)

at com.handmark.pulltorefresh.library.AutoLoadMoreListView$LoadMoreListView.dispatchDraw(SourceFile:359)

at com.handmark.pulltorefresh.library.AutoLoadMoreListView$InternalListView.dispatchDraw(SourceFile:470)

at android.view.View.draw(View.java:14479)

at android.widget.AbsListView.draw(AbsListView.java:3877)

at android.view.View.getDisplayList(View.java:13373)

at android.view.View.getDisplayList(View.java:13415)

at android.view.View.draw(View.java:14193)

at android.view.ViewGroup.drawChild(ViewGroup.java:3103)

at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)

at android.view.View.getDisplayList(View.java:13368)

at android.view.View.getDisplayList(View.java:13415)

at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)

at android.view.View.getDisplayList(View.java:13311)

at android.view.View.getDisplayList(View.java:13415)

at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)

at android.view.View.getDisplayList(View.java:13311)

at android.view.View.getDisplayList(View.java:13415)

at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)

at android.view.View.getDisplayList(View.java:13311)

at android.view.View.getDisplayList(View.java:13415)

at android.view.View.draw(View.java:14193)

at android.view.ViewGroup.drawChild(ViewGroup.java:3103)

at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)

at android.view.View.getDisplayList(View.java:13368)

at android.view.View.getDisplayList(View.java:13415)

at android.view.View.draw(View.java:14193)

at android.view.ViewGroup.drawChild(ViewGroup.java:3103)

at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)

at android.view.View.getDisplayList(View.java:13368)

at android.view.View.getDisplayList(View.java:13415)

at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)

at android.view.View.getDisplayList(View.java:13311)

at android.view.View.getDisplayList(View.java:13415)

at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)

at android.view.View.getDisplayList(View.java:13311)

at android.view.View.getDisplayList(View.java:13415)

at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)

at android.view.View.getDisplayList(View.java:13311)

at android.view.View.getDisplayList(View.java:13415)

at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)

at android.view.View.getDisplayList(View.java:133

请问是否我的代码写法有误,如果是这样,这样的场景下,应该如何获取bitmap对象来使用SpannableString呢?希望你们能看懂中文。感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值