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

Posted everlastxgb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bitmap.createBitmap创建的新bitmap可能与原始bitmap是一个对象相关的知识,希望对你有一定的参考价值。

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



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

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

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是否相等即可。

以上是关于Bitmap.createBitmap创建的新bitmap可能与原始bitmap是一个对象的主要内容,如果未能解决你的问题,请参考以下文章

Bitmap.createBitmap 导致内存溢出的考虑

Bitmap.createBitmap 导致内存溢出的考虑

Android Bitmap

Android 获取View的Bitmap

Android 获取View的Bitmap

Android 获取View的Bitmap