0

我正在创建一个调用BitmapRegionDecoder.decodeRegion(Rect, BitmapFactory.Options). 我正在处理以前从decodeRegion每次调用之前获得的位图:

//this is a function I wrote that gets the rectangle I need
//from the zoom/pan state of a lower-resolution ImageView (page).
//it is bragable.
Rect areaRect = page.getBitmapRegionDecoderRect(areaBitmapRect);
BitmapFactory.Options options = new BitmapFactory.Options();

//area is the ImageView which will get the hi-res bitmap in it.
if(area.getHeight()!=0)
{
//I used Math.round because we are so desperate to save memory!
//The consequent blurring is actually not too bad.
    options.inSampleSize = Math.round( ((float) areaRect.height()) / ((float) area.getHeight()) );
}
else
{
    options.inSampleSize = Math.round( ((float) areaRect.height()) / ((float) page.getHeight()) );
}
if(options.inSampleSize==0) options.inSampleSize=1;
if(options.inSampleSize>16) options.inSampleSize=16;
options.inPreferredConfig = Bitmap.Config.RGB_565;
if(areaRect.left<0) areaRect.left = 0;
if(areaRect.right>areaBitmapRect.right) areaRect.right = areaBitmapRect.right;
if(areaRect.top<0) areaRect.top = 0;
if(areaRect.bottom>areaBitmapRect.bottom) areaRect.bottom = areaBitmapRect.bottom;
if(areaBitmap!=null)
{
//recycling our garbage ... or are we?
    areaBitmap.recycle();
    areaBitmap = null;
    try
    {
//dirty hack
        wait(200);
    }
    catch(Exception x)
    {
//something happened.
    }
}
//the all-important call
areaBitmap = areaDecoder.decodeRegion(areaRect, options);
area.setImageBitmap(areaBitmap);

我遇到了一个问题,即在非常快速的连续 UI 事件中,我们的内存不足。正如你所看到的,我已经用肮脏的黑客“解决”了这个问题(线程等待 200 毫秒并给 Android 一些时间来赶上)。

出于显而易见的原因,我对此不太满意。首先,我的诊断(在我们分配新内存之前垃圾收集没有完成)是否正确?其次,我试着把

while(!areaBitmap.isRecycled())

调用后计数器递增,recycle()计数器保持为零。我看到了isRecycled()这样做的意义,但我需要类似isCompletelyRecycled()方法的东西。Android有这样的东西吗?第三,如果我对此无能为力,是否有一种“可用内存”方法可以用来判断我的电话是否会将我们推倒?我找不到一个。如果 Android 会说更多核心可用但对你没有,那就太好了,所以我可以将我的等待循环称为 B 计划,或者最终尝试一些不那么密集的东西。

4

2 回答 2

2

Bitmap memory is allocated in the native heap, so System.gc() will not help. The native heap has its own GC, but clearly it is is not kicking in quickly enough for you - and I am not aware of any way to force it (ie there is not a native analogue of System.gc()).

You could change the structure of your application as Nicklas A suggests to re-use your bitmap.

Or you could use the native heap monitoring mechanisms detailed in BitmapFactory OOM driving me nuts to determine when it is safe to allocate a new bitmap.

于 2011-07-08T17:19:30.100 回答
0

尝试跑步System.gc()而不是睡眠。


实际上我不确定这是否会有所帮助,因为位图似乎主要是本机代码,这意味着它应该在调用回收时立即释放。


对我来说,在每个 UI 事件上创建一个新位图似乎是个坏主意,你不能只创建一个位图并编辑那个位图吗?

于 2011-07-08T17:10:17.790 回答