Bitmap.createBitmap创建的新bitmap可能与原始bitmap是一个对象

无意间看到Bitmap.createBitmap的源码,发现其中有一句很有趣的话 “The new bitmap may be the same object as source, or a copy may have been made”。如下图:

Bitmap.createBitmap创建的新bitmap可能与原始bitmap是一个对象_第1张图片


于是乎,搜索了相关内容,看到有一篇文章遇到一种情况,大概是这样的:

 当图像的旋转角度小于两个像素点之间的夹角时,图像即使选择也无法显示,因此,系统完全可以认为图像没有发生变化,因此,就将他们共用一个对象。测试代码(摘录)如下:

ImageView imageView = (ImageView) findViewById(R.id.test);
Matrix matrix = new Matrix();
matrix.setRotate(0.013558723994643297f);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Bitmap targetBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
if (!bitmap.isRecycled()) {
    bitmap.recycle();
}
imageView.setImageBitmap(targetBmp);


这个bug大概是这样的,从bitmap创建出targetBmp后,对bitmap执行recycle(),此时调用targetBmp出现异常,如下:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.xys.preferencetest, PID: 30512
                  java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1a50ff6b



原因很简单,由于旋转的角度几乎为0,基于节省内存占用,targetBmp被视为和bitmap一样,指向同一个对象,即出现了“may be the same object as source”。因此,相当于对一个bitmap对象进行了recycle后重新引用其方法,故异常。

为了解决这个bug,其实也很简单,判断下bitmap和targetBmp是否相等即可。

你可能感兴趣的:(疑难杂症)