因為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; }