有人可以通过最佳实践来清除敏感的运行时映像吗?
考虑这样一种情况:在运行时从服务器下载敏感图像,加载到Bitmap对象中,然后在片段中的ImageView中显示。
当用户离开该屏幕,或者应用程序长时间退出/放入后台时,我想清除该图像数据,以便不易恢复。
我想知道一旦包含图像的片段被破坏,是否有可靠的方法将位图数据清零?
这对我来说很棘手,因为Bitmaps通常作为不可变对象返回,例如BitmapFactory.decodeByteArray说:
从指定的字节数组中解码不可变的位图。
据推测,我必须创建一个可变Bitmap,然后复制其数据?
看起来recycle()对我没有帮助,因为这只是将数据标记为可用于垃圾收集,它不会擦除它。
答案 0 :(得分:2)
您只需使用
清除Bitmap
即可
someBitmap.eraseColor(android.graphics.Color.TRANSPARENT);
它会用TRANSPARENT
颜色填充位图并删除其上的所有内容。
但是,如果您没有对您的位图的任何引用(例如,您已将null
设置为ImageView
,而Bitmap
包含此类
someImageView.setDrawable(null)
垃圾收集器应该很快收集它。
答案 1 :(得分:1)
感谢@IlyaGulya提出的eraseColor
建议。下面是我到目前为止编写的代码。
创建可变位图:
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inMutable = true;
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, bitmapOptions);
清除片段中图像数据的代码(我在Fragment收到时将BitmapDrawable保存到myBitmapDrawable
字段中):
@Override
public void onDestroy() {
myImageView.setImageDrawable(null);
try {
MyUtils.zeroOutBitmapData(myBitmapDrawable.getBitmap());
} catch (Exception e) {
loggingUtil.logHandledException(e);
}
super.onDestroy();
}
我的实用程序用于清零位图:
public static void zeroOutBitmapData(Bitmap mutableBitmap) {
if (mutableBitmap.isMutable()) {
mutableBitmap.eraseColor(android.graphics.Color.TRANSPARENT);
} else {
logger.error("Expected bitmap to be mutable");
}
}
...这里是一个单元测试(好吧,ApplicationTestCase
,因为我想测试一个真正的Bitmap):
public void testZeroOutBitmap() throws Exception {
Resources resources = getContext().getResources();
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inMutable = true;
Bitmap mutableBitmap = BitmapFactory.decodeResource(resources, R.drawable.an_example_image);
// Assert that some pixels start out with non zero colors
assertEquals(-789517, mutableBitmap.getPixel(0, 0));
assertEquals(-723724, mutableBitmap.getPixel(10, 10));
MyUtils.zeroOutBitmapData(mutableBitmap);
// Check that pixel data has now been cleared out
assertEquals(android.graphics.Color.TRANSPARENT, mutableBitmap.getPixel(0, 0));
assertEquals(android.graphics.Color.TRANSPARENT, mutableBitmap.getPixel(10, 10));
}