只有Android 4.1,位图是自动回收的



我遇到了一个非常关键的问题。只有Android 4.1,位图是自动回收的!我的代码中没有调用recycle()!我的项目在任何分辨率的其他操作系统版本(~4.0.3)中都能很好地工作。其他项目也有同样的问题。

所有图像文件都在可绘制的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;
}

在我的测试中,

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

ex)int width=100

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

宽度=200

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

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

  • 在相同的解决方案中,如果我更改图像文件文件夹的名称,问题会出现在其他位图实例中。可绘制nodpi->可绘制ldpi。。。,可绘制的xdpi。

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

int宽度=100;

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

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

请。。。我能做什么?!T^T

您从不同大小获得不同结果的原因可能是,如果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位图对象的引用。当然,您可以使用任何需要的位图配置。

我相信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;
}

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

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

最新更新