Android中Bitmap回收问题

 陈民翔芷昌柏淑 发布于 2022-10-30 15:26

使用Bitmap的静态方法createScaledBitmap来创建一个符合规格的Bitmap的时候,原生的bitmap是否需要回收?

代码如下:

private void initDragBitmap() {
    Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mingren);
    mDragBitmap = Bitmap.createScaledBitmap(srcBitmap, FLOAT_BALL_WIDTH, FLOAT_BALL_HEIGHT, true);
    srcBitmap.recycle();
}

代码中srcBitmap是否需要回收?


补充问题:

看了大家的回复,基本可以确定如果srcBitmap后续不再使用了,确实是可以手动recycle的,同时它本身也是个局部变量,是可以等待系统GC的。

那新问题来了(或者说我最初想问的问题来了),当createScaledBitmap方法中传入的宽和高跟srcBitmap相同时,通过createScaledBitmap代码注释可以看出它是将srcBitmap返回了,这个时候我强行recycle了srcBitmap,会不会导致mDragBitmap也为null?

源码注释:

    /**
     * Creates a new bitmap, scaled from an existing bitmap, when possible. If the
     * specified width and height are the same as the current width and height of
     * the source bitmap, the source bitmap is returned and no new bitmap is
     * created.
     *
     * @param src       The source bitmap.
     * @param dstWidth  The new bitmap's desired width.
     * @param dstHeight The new bitmap's desired height.
     * @param filter    true if the source should be filtered.
     * @return The new scaled bitmap or the source bitmap if no scaling is required.
     * @throws IllegalArgumentException if width is <= 0, or height is <= 0
     */
    public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,
            boolean filter) {
            }
5 个回答
  • 带现在的主流版本上,Google已经将Bitmap的内存放到堆中去了,这个回收也交给了gc,所以楼主不用考虑这个这个问题了。内存不够时就自动回收了。

    2022-11-12 01:47 回答
  • /*Free the native object associated with this bitmap, and clear the
     * reference to the pixel data. This will not free the pixel data synchronously;
     * it simply allows it to be garbage collected if there are no other references.
     * The bitmap is marked as "dead", meaning it will throw an exception if
     * getPixels() or setPixels() is called, and will draw nothing. This operation
     * cannot be reversed, so it should only be called if you are sure there are no
     * further uses for the bitmap. This is an advanced call, and normally need
     * not be called, since the normal GC process will free up this memory when
     * there are no more references to this bitmap.
     */
    public void recycle() {
        if (!mRecycled && mFinalizer.mNativeBitmap != 0) {
            if (nativeRecycle(mFinalizer.mNativeBitmap)) {
                // return value indicates whether native pixel object was actually recycled.
                // false indicates that it is still in use at the native level and these
                // objects should not be collected now. They will be collected later when the
                // Bitmap itself is collected.
                mBuffer = null; 
                mNinePatchChunk = null;
            }
            mRecycled = true;
        }
    }
    回复3楼,@xialong
    可以看到,源码也是将数据制为`null`,一般情况下,你可以`bitmap.recycle()`与`bitmap=null`一起用;
    
    题主确定不需要用到那个`bitmap`就可以手动回收,`recycle()`的回收是`不可逆`的
    2022-11-12 01:47 回答
  • private void initDragBitmap() {

    Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mingren);
    mDragBitmap = Bitmap.createScaledBitmap(srcBitmap, FLOAT_BALL_WIDTH, FLOAT_BALL_HEIGHT, true);
    srcBitmap.recycle();

    }

    就题主以上代码,和大家探讨个问题,是不是用srcBitmap=null;可以尽快让gc回收呢?

    2022-11-12 01:47 回答
  • 如果你确信没有进一步的操作就可以调用其recycler方法,释放内存;如果后续有getPixels()setPixels()的调用就不要随意释放内存,等待GC的回收,否则会抛异常。

    2022-11-12 01:47 回答
  • 你可以等待GC去回收,当然,像你这样手动回收是个好习惯。

    补答:

    会的,如果两个引用都是同一个对象,那么你使用recycle时会让对象中的图片被清理。不过清理的是对象中的图片数据,并不是对象本身,所以说mDragBitmap不会为null,但是使用mDragBitmap中的图片数据时会报错。

    你这里可以进行进行一次判断再回收:

    if (srcBitmap != mDragBitmap) {  // 内存地址不同,说明不是同一个对象
        srcBitmap.recycle();
    }
    2022-11-12 01:47 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有