我在磁盘上有 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 时。