只有Android 4.1,Bitmap会自动回收

时间:2012-10-15 06:56:20

标签: android bitmap drawable android-4.2-jelly-bean recycle

我有非常严重的问题。 只有Android 4.1,Bitmap会自动回收! 我没有在我的代码中调用recycle()! 我的项目在其他操作系统版本(~4.0.3)中可以正常使用任何分辨率。 其他项目也有同样的问题。

所有图像文件都在drawable-nodpi文件夹中。 我总是调整它们以适应任何设备的分辨率。

public Bitmap GetBitmap(int resource){

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inDither = true;
    options.inPurgeable = true;

    Bitmap tmp = null;

    try{
        tmp = BitmapFactory.decodeResource(mResources, resource, options);
    }catch(OutOfMemoryError e){
        options.inSampleSize = 2;
        tmp = BitmapFactory.decodeResource(mResources, resource, options);
    }

    return tmp;
}

public Bitmap GetScaledBitmap(int resource, int width, int height, boolean filter){

    Bitmap tmp = GetBitmap(resource);

    Bitmap img = Bitmap.createScaledBitmap(tmp, width, height, filter);

    tmp.recycle();
    tmp = null;

    return img;
}

在我的测试中,

  • 相同的位图实例,但出现问题取决于调整大小值。

离) int width = 100 ;

Bitmap imgStar = MyResourceManager.getInstance()。GetScaledBitmap(R.drawable.star,width,width,true); - >返回循环实例。

width = 200 ;

imgStar = MyResourceManager.getInstance()。GetScaledBitmap(R.drawable.star,width,width,true); - >返回普通实例。

  • 在不同的分辨率下,imgStar工作正常,但问题出现在其他位图实例中。 同样,当我更改调整大小值时,它可以正常工作。

  • 在同一分辨率下,如果我更改图像文件文件夹的名称,则会在其他位图实例中出现问题。 drawable-nodpi - > drawable - > drawable-ldpi,...,drawable-xdpi。

  • 相同的调整大小值,如果我放入其他资源ID,它可以正常工作。 前)

int width = 100;

位图imgStar = MyResourceManager.getInstance()。GetScaledBitmap(R.drawable。 star ,width,width,true); - >返回循环实例。

imgStar = MyResourceManager.getInstance()。GetScaledBitmap(R.drawable。 diamond ,width,width,true); - >返回普通实例。

请......我该怎么办?! T ^ T

3 个答案:

答案 0 :(得分:6)

您从不同大小获得不同结果的原因可能是因为如果原始对象与您缩放的大小相同,则createScaledBitmap将返回原始对象。

我有同样的问题,做同样的事情。我能够以这种方式修复它:

public Bitmap GetScaledBitmap(int resource, int width, int height, boolean filter) {

    Bitmap tmp = GetBitmap(resource);
    Bitmap img = Bitmap.createScaledBitmap(tmp, width, height, filter);
    //copy the image to be sure you are not using the same object as the tmp bitmap
    img=img.copy (Bitmap.Config.RGB_565,false);
    tmp.recycle();
    tmp = null;
    return img;
}

这里我复制了位图,以确保在我回收tmp位图之前它不仅仅是对tmp位图对象的引用。当然,您可以使用您需要的任何位图配置。

答案 1 :(得分:2)

我相信XdebugX在他的发现中是正确的,尽管你不需要创建副本。只需检查调整大小的位图和原始位图之间的内存位置是否相同。

public Bitmap GetScaledBitmap(int resource, int width, int height, boolean filter){

    Bitmap tmp = GetBitmap(resource);
    if (tmp == null) {
        return null;
    }

    Bitmap img = Bitmap.createScaledBitmap(tmp, width, height, filter);

    /***
     * Bitmap#createScaledBitmap will return the original object
     * if it is the same size you are scaling to.
     */
    if (tmp != img) {
        Log.d(TAG, "Full size image recycled");
        tmp.recycle();
    } else {
        Log.w(TAG, "Resized bitmap was the same as the fullsize bitmap");
    }

    return img;
}

答案 2 :(得分:0)

我宁愿建议在回收之前检查位图是否已经回收:

if (!tmp.isRecycled()) tmp.recycle();