2011-07-08 171 views
0

我正在創建一個查看器應用程序,它調用BitmapRegionDecoder.decodeRegion(Rect, BitmapFactory.Options)。我從配置各decodeRegion調用前在過去得到了位圖:有沒有辦法告訴Bitmap是否已經在Android上完全處置?

//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事件,我們正在運行的內存事實問題。正如你所看到的,我已經用骯髒的黑客「解決了」這個問題(線程等待200ms,讓Android有一段時間趕上)。

我對此並不滿意,原因很明顯。首先,我的診斷(在我們分配新內存之前垃圾回收沒有完成)是否正確?其次,我試圖把

while(!areaBitmap.isRecycled()) 

圍繞一個計數器增量recycle()電話後,計數器停留在零。我看到isRecycled()這樣做,但我需要像isCompletelyRecycled()方法。 Android有這樣的東西嗎?第三,如果我無法得到任何答案,是否有一種「可用記憶」方法可以用來判斷我的電話是否會推動我們?我找不到一個。如果Android會說更多的核心可用但對你而言不是很好,那麼我可以將我的等待循環稱爲計劃B,或者最終嘗試一些不太密集的東西。

回答

2

位圖內存分配在本機堆中,因此System.gc()將無濟於事。本地堆有它自己的GC,但顯然它並沒有足夠快地爲你踢 - 我不知道有什麼辦法強制它(即沒有System.gc()的本地模擬)。

您可以更改您的應用程序的結構,因爲Nicklas A建議重新使用您的位圖。

或者您可以使用BitmapFactory OOM driving me nuts中詳述的本機堆監視機制來確定何時分配新的位圖是安全的。

+0

Ah-so System.gc()可能適用於等待(200)完全相同的原因(即它們觸發延遲)。我提到了爲什麼我無法避免創造新的位圖,儘管我有一些想法讓它不那麼頻繁;文章中的方法正是我所期待的。謝謝! –

+0

我已編輯標題以反映解決方案的特定位圖。謝謝! –

0

嘗試運行System.gc()而不是睡覺。


其實我不確定這是否會有助於爲位圖似乎是大多本地代碼意味着它應該儘快回收被稱爲釋放。


對我來說,好像每個UI事件創建一個新的位圖似乎是一個壞主意,不能你只是創建一個位圖和編輯一個?

+0

System.gc()似乎工作。我們不能編輯位圖:問題是我們的源位圖很大(類似於2000×3000),因此需要首先使用BitmapRegionDecoder。可能會有一個折中的解決方案(比我們所需要的略大一點的位圖可以減少小盤子/縮放的重新加載)。 –

+0

我會建議不要經常創建位圖,因爲它是一個沉重的操作,尤其是如果它與用戶界面相關。 –

+0

相信我,我不想。我已經編輯了標題,因爲答案與位圖相關的內容超過一般內存。 –

相關問題