解決在 Android 中使用 Bitmap 造成 Out of memory 的方法~

因為Android本身的限制,在2.x版中使用 Bitmap 只要遇到稍大一點的圖,很容易就會遇到 out of memory 的狀況,在經過一陣搜尋之後,一直沒有很好的方法,有很多網站介紹的方法是把原圖 subsample,但對於圖片quality有要求的程式來說,這可是不被接受的解法,搞了半天,最後只好直接把 Android 的 source code 拿出來瞧瞧看看是否有什麼機會解決這個問題,突然發現原來這個問題竟然有個投機取巧的解決方法。

 

目前在網站上找到的結果,效果最有效的是使用 

BitmapFactory.Options 

將裏面的 inPurgeable 設定為 true,這樣可以讓java系統記憶體不足時先行回收部分的記憶體,這個方法其實已經解決大部分的問題了,不過生出來的記憶體還是算在java 的VM裏總是有些美中不足。

在看了source code 之後,我發現在BitmapFactory.Options裏竟然有一個inNativeAlloc的public變數,可以直接不把使用的記憶體算到VM裏,有趣的是這個變數是個隱藏版的變數,所以在正常的SDK文件中看不到,用eclipse時也不會提示你,也不能直接用,因此我用了一些小技巧將這個變數設成true,如此一來bitmap out of memory的問題發生的機率又更低了,以下就是目前的程式碼,有需要的人可以參考一下,不過不管怎麼樣,bitmap這東西,只要不用了,還是請儘量將它recycle,不然再多記憶體也是不夠用地~

public Bitmap decodeFile(String filePath)
{
    Bitmap bitmap = null;
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inPurgeable = true;
    try {
		BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options,true);
	} catch (IllegalArgumentException e) {
		e.printStackTrace();
	} catch (SecurityException e) {
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		e.printStackTrace();
	} catch (NoSuchFieldException e) {
		e.printStackTrace();
	}

	if(mFilePath != null)
	{
		bitmap = BitmapFactory.decodeFile(mFilePath, options);				
	}
	
	return bitmap;
}

你可能感兴趣的:(android)