Bitmap.recycle引发的血案

在Android中,Bitmap的存储分为两部分,一部分是Bitmap的数据,一部分是Bitmap的引用。
在Android2.3时代,Bitmap的引用是放在堆中的,而Bitmap的数据部分是放在栈中的,需要用户调用recycle方法手动进行内存回收,而在Android2.3之后,整个Bitmap,包括数据和引用,都放在了堆中,这样,整个Bitmap的回收就全部交给GC了,这个recycle方法就再也不需要使用了。

真的,一定不能再用了啊啊啊啊啊。。。。。。。。。。。

现在的SDK中对recycle方法是这样注释的,可以发现,[系统]建议你不要手动去调用,而是让GC来进行处理不再使用的Bitmap。我们可以认为,即使在Android2.3之后的版本中去调用recycle,系统也是会强制回收内存的,只是系统不建议这样做而已。

这个bug的起因是因为我们的一张图片需要旋转,同时可以设置一个旋转角度,老的代码是这样写的:

public static Bitmap rotateBitmap(Bitmap sourceBitmap, int degress, boolean frontCamera) {
        Matrix matrix = new Matrix();
        matrix.postRotate(degress);
        if (frontCamera) {
            if (degress == 90 || degress == 270) {
                matrix.postScale(1, -1);
            } else {
                matrix.postScale(-1, 1);
            }
        }
        Bitmap rotaBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, false);
        return rotaBitmap;
    }

从上面的代码可以很明显的看到我是新create了一个 “新” Bitmap,但是真的新么,不见得啊!!!
按道理来说,bitmap与create出来的rotaBitmap应该是两个对象,当旋转角度正常的时候,确实也是这样,但当旋转角度比较奇葩的时候(这里我旋转了0度),这两个bitmap对象居然变成了同一个!而打开Bitmap.createBitmap的代码,可以发现如下所示的注释:

1778289-6c988f54a2fbdd3b.png

image.png

The new bitmap may be the same object as source, or a copy may have been made. It is initialized with the same density as the original bitmap.
可能为同一个Bitmap!!!google为了省内存真是666了

当图像的旋转角度小余两个像素点之间的夹角时,图像即使选择也无法显示,因此,系统完全可以认为图像没有发生变化,因此,注释中的情况,就是这种情况了。

血泪史,2.3后不要在用recycle来干事了,GC不是吃屎的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值