Android 使用Glide加载图像时遇到错误:Can';t对回收的位图调用重新配置()

Android 使用Glide加载图像时遇到错误:Can';t对回收的位图调用重新配置(),android,bitmap,transform,android-glide,Android,Bitmap,Transform,Android Glide,我犯了一个错误 无法对回收的位图调用重新配置() 使用Glide库加载图像时。5次中有1次我会出现此错误。图像大小约为1.5MB 我使用的是Glide的3.8.0版 以下是我的转换代码: public class ScaleToFitWidthHeightTransform extends BitmapTransformation { int mSize = AppConstants.HEIGHT_TRANSFORM_LIMIT; //1020 boolean isHeightScale;

我犯了一个错误

无法对回收的位图调用重新配置()

使用Glide库加载图像时。5次中有1次我会出现此错误。图像大小约为1.5MB

我使用的是Glide的3.8.0版

以下是我的转换代码:

public class ScaleToFitWidthHeightTransform extends BitmapTransformation {
int mSize = AppConstants.HEIGHT_TRANSFORM_LIMIT; //1020  
boolean isHeightScale;

public ScaleToFitWidthHeightTransform(Context context) {
    super(context);
}

public Bitmap transform(Bitmap source) {
    float scale;
    int newSize;
    int sourceHeight = source.getHeight();
    int sourceWidth = source.getWidth();

    // If original bitmap height/width is less then the height/width transform limit
    // then no need to scale the bitmap, so return the original bitmap
    if (sourceHeight < AppConstants.HEIGHT_TRANSFORM_LIMIT && sourceWidth < AppConstants.WIDTH_TRANSFORM_LIMIT) { // Height and width limit is 1020.
        return source;
    }
    Bitmap scalBitmap;

    if (sourceHeight > sourceWidth) {
        scale = (float) AppConstants.HEIGHT_TRANSFORM_LIMIT / source.getHeight();
        newSize = Math.round(source.getWidth() * scale);
        scaleBitmap = Bitmap.createScaledBitmap(source, newSize, mSize, true);
    } else {
        scale = (float) AppConstants.WIDTH_TRANSFORM_LIMIT / source.getWidth();
        newSize = Math.round(source.getHeight() * scale);
        scaleBitmap = Bitmap.createScaledBitmap(source, mSize, newSize, true);
    }
    if (scaleBitmap != source) {
        source.recycle();
    }

    return scaleBitmap;
}

@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
    return  transform(toTransform);
}

@Override
public String getId() {
    return "com.abc";
}
公共类ScaleToFitWidthHeightTransform扩展了位图转换{
int mSize=AppConstants.HEIGHT\u TRANSFORM\u LIMIT;//1020
布尔尺度;
公共缩放FitWidthHeightTransform(上下文){
超级(上下文);
}
公共位图转换(位图源){
浮标;
int newSize;
int sourceHeight=source.getHeight();
int sourceWidth=source.getWidth();
//如果原始位图的高度/宽度小于高度/宽度变换限制
//然后不需要缩放位图,因此返回原始位图
如果(sourceHeight源宽度){
scale=(float)AppConstants.HEIGHT_TRANSFORM_LIMIT/source.getHeight();
newSize=Math.round(source.getWidth()*scale);
scaleBitmap=Bitmap.createScaledBitmap(源、新闻大小、mSize、true);
}否则{
scale=(float)AppConstants.WIDTH_TRANSFORM_LIMIT/source.getWidth();
newSize=Math.round(source.getHeight()*scale);
scaleBitmap=Bitmap.createScaledBitmap(源、mSize、newSize、true);
}
if(scaleBitmap!=源){
source.recycle();
}
返回scaleBitmap;
}
@凌驾
受保护的位图转换(位图池、位图转换、int-out-idth、int-out-height){
返回变换(toTransform);
}
@凌驾
公共字符串getId(){
返回“com.abc”;
}
以下是我使用Glide的行

        Glide.with(context)
                .load(imageUri).asBitmap()
                .transform(new ScaleToFitWidthHeightTransform(context))
                .placeholder(defaultDrawable)
                .error(defaultDrawable)
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                        BitmapSourceData bitmapSourceData = null;
                        bitmapSourceData = new BitmapSourceData();
                         bitmapSourceData.setBitmapSource(getBitmapBytes(resource));

                        if (imageView != null) {
                            imageView.setImageBitmap(resource);
                        }                           
                 }

                        @Override
                        public void onLoadFailed(Exception e, Drawable errorDrawable) {
                            super.onLoadFailed(e, errorDrawable);
                            Log.e("ABC", "Exception --> " + e.toString());
                }); // Here I am getting error printed.
Glide.with(上下文)
.load(imageUri).asBitmap()
.transform(新的ScaleToFitWidthHeightTransform(上下文))
.占位符(可默认绘制)
.错误(可默认绘制)
.into(新的SimpleTarget(){
@凌驾

public void onResourceReady(位图资源,GlideAnimation您已在此处回收位图

if (scaleBitmap != source) {
    source.recycle();
}
不要这样做


此外,createScaledBitmap是一项非常繁重的操作,请避免使用它。您可以使用画布和矩阵缩放位图。

您不必回收位图。只需观察引用计数。如果不再引用位图,GC将痛苦地踢入并为您清理它。这只是一个标志,表明它可以更快地被GC删除。

从位图文档中了解回收方法:

/** *释放与此位图关联的本机对象,然后清除 *引用像素数据。这不会同步释放像素数据; *它只允许在没有其他引用的情况下对其进行垃圾收集。 *位图被标记为“死”,这意味着如果 *调用getPixels()或setPixels(),将不绘制任何内容。此操作 *无法反转,因此只有在确定没有 *位图的进一步使用。这是一个高级调用,通常需要 *无法调用,因为正常的GC进程将在 *不再有对此位图的引用


如果我不回收不需要的位图,它可能会创建内存溢出异常。