我在磁盘上有1280x1280 JPG,我正在使用以下代码解码图像区域(剪切两侧)以在ImageView中显示。剪裁图像的顶部和底部存在类似的问题。
private Bitmap decodeBitmapRegion(InputStream in, Rect region, Bitmap recycleBitmap) {
LOGD(TAG, "decodeBitmapRegion region=" + region + ", recycleBitmap=" + recycleBitmap );
Bitmap bitmap = null;
BitmapRegionDecoder decoder = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
options.inBitmap = recycleBitmap;
try {
decoder = BitmapRegionDecoder.newInstance(in, false);
bitmap = decoder.decodeRegion(region, options);
} catch (IllegalArgumentException e){
LOGE(TAG, "Failed to recycle bitmap for rect=" + region, e);
} catch (IOException e) {
LOGE(TAG, "Failed to decode into rect=" + region, e);
} finally {
if (decoder != null) decoder.recycle();
}
return bitmap;
}
在Acer Iconia A100(4.0.3)上,代码完美运行并将区域解码为循环位图(如果提供),在堆上不分配内存。 logcat没有GC或增加堆消息。它也可以在运行4.2.0的Nexus 7上正常工作。
在Motorola Xoom(4.0.4)上,代码生成以下logcat。第一个dalvikvm-heap增长(4738256字节)可能是BitmapRegionDecoder的数据,第二个(3603216字节)匹配存储图像所需的内存量(800x1126x4)。还有一个skia错误。
8522 LocationImageLoader D decodeBitmapRegion region=Rect(240, 77 - 1040, 1203), recycleBitmap=android.graphics.Bitmap@415319a8
8522 dalvikvm D GC_FOR_ALLOC freed 8213K, 28% free 22782K/31623K, paused 34ms
8522 dalvikvm-heap I Grow heap (frag case) to 26.808MB for 4738256-byte allocation
8522 dalvikvm D GC_CONCURRENT freed 6K, 14% free 27403K/31623K, paused 3ms+7ms
8522 skia D WARNING: One-shot allocator has already allocated (alloc count = 1)
8522 dalvikvm D GC_FOR_ALLOC freed 0K, 14% free 27403K/31623K, paused 33ms
8522 dalvikvm-heap I Grow heap (frag case) to 30.238MB for 3603216-byte allocation
8522 dalvikvm D GC_FOR_ALLOC freed 0K, 3% free 30922K/31623K, paused 41ms
设置options.inPreferredConfig = Bitmap.Config.RGB_565;似乎否定了Xoom上的第二个分配,好像位图被正确回收,但仍然为解码器分配了内存。
使用完整图像(1280x1280)和BitmapFactory进行回收虽然可以使用比本地区要求更多的内存来存储整个图像。
我无法理解为什么Xoom不起作用,但当两者都运行Android 4.0.x时,Acer都没问题。
答案 0 :(得分:2)
我注意到我的Archos G9 80(4.0.4)返回的Bitmaps正在使用RGB8888,即使我请求了RGB656。如果我解码1024x1024平方并在生成的位图上调用getByteCount(),则返回4MB。即使我使用RGB8888传入一个位图,它仍然会分配一个新的。
如果您注意到文档,则表示选项用于inSampleSize,它看似起作用,但没有特别提及inPreferredConfig和inBitmap的使用。我想这意味着尊重inPreferredConfig和inBitmap取决于制造商或在4.1 +中添加。
答案 1 :(得分:1)
您是在回收recycleBitmap吗?
值得注意的是,有时回收的位图是某些操作中返回的实际位图,因此您不想回收它。但是有时候会实例化一个新的位图,在这种情况下你想要回收原始的位图 - 假设它不再需要超出这个方法的范围。