Android加载图片OOM错误解决方式
?
前幾天做項目的時候,甲方要求是PAD (SAMSUNG P600 10.1寸 2560*1600)的PAD上顯示高分辨率的大圖片。
SQLITE採用BOLD方式存儲圖片,這個存取過程就不說了哈,網(wǎng)上一大堆。
可是在加載/讀取/顯示圖片的時候會報OOM錯誤,上網(wǎng)查了非常多解決方式還繞了非常多彎路,最后還是找到了原因所在。以下從幾個方面來解釋一下OOM問題的解決方式。
(謝謝周同學的“尺寸”提醒。不然我可能一輩子都要蒙在鼓里)
?
1.Android APP內(nèi)存
做一個APP開發(fā)的時候,還是不要想著去擴大Android系統(tǒng)賦予的內(nèi)存上限了。部分老機型老系統(tǒng)16M。大部分都是24M了。
一些大型游戲用dalvik.system.VMRuntime來干涉GC過程(這個類我還沒有學過。
。
。剛聽說不久)。
據(jù)說用NDK開發(fā)時候,C能夠動態(tài)申請多余的內(nèi)存空間,可是我沒用過NDK,今后也不打算用了(個人原因)。
?
2.圖片文件大小
甲方給了一大堆文件大小不一的圖片,在加載數(shù)據(jù)庫->讀取出來->顯示出來的這個過程中,出現(xiàn)了非常多OOM,分為:
a.加載圖片時使用ByteArrayStream創(chuàng)建流,size為Height * Width * 4。OOM;
b.讀取圖片時候OOM,同上;
c.顯示圖片時候OOM,decodeResource函數(shù)報錯,OOM;
開始時候以為是文件大小問題。后來發(fā)現(xiàn)有些2M的圖片都能顯示,可是某些1M的圖片確報錯。所以在一定范圍內(nèi),能夠證明。圖片OOM問題與文件大小無關。
?
3.圖片尺寸(分辨率)
調(diào)查這些能顯示的圖片和不能顯示的圖片的不同。發(fā)現(xiàn)長寬差距非常大。那些能成功顯示的圖片為1005*1500大小,而其它圖片都是3000*5000以上。
我用PAINT(一款適合小白的圖像處理軟件。盡管不如PS可是功能已經(jīng)很強大了,最新版須要安裝NET 4.5)壓縮了圖片大小。壓縮到1005*1500。顯示成功。
?
4.函數(shù)調(diào)用
閱讀了這位大神的博客:
http://blog.csdn.net/huangbiao86/article/details/8072128
摘取當中最精華的部分吧:
盡量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource來設置一張大圖,由于這些函數(shù)在完畢decode后。終于都是通過java層的createBitmap來完畢的。須要消耗很多其它內(nèi)存。
?
因此,改用先通過BitmapFactory.decodeStream方法,創(chuàng)建出一個bitmap,再將其設為ImageView的 source,decodeStream最大的秘密在于其直接調(diào)用JNI>>nativeDecodeAsset()來完畢decode。無需再使用java層的createBitmap,從而節(jié)省了java層的空間。
假設在讀取時加上圖片的Config參數(shù),能夠跟有效降低載入的內(nèi)存。從而跟有效阻止拋out of Memory異常
另外。decodeStream直接拿的圖片來讀取字節(jié)碼了。 不會依據(jù)機器的各種分辨率來自己主動適應,?使用了decodeStream之后,須要在hdpi和mdpi,ldpi中配置對應的圖片資源,?否則在不同分辨率機器上都是相同大小(像素點數(shù)量),顯示出來的大小就不正確了。
看來讀底層源代碼還是非常實用的,setImageBitmap 和 setImageResource 和 decodeResource在運行過程中還是調(diào)用了createBitmap來創(chuàng)建一個新的bitmap。創(chuàng)建bitmap會加劇內(nèi)存消耗,所以不推薦使用了。應該使用decodeStream方法。
圖片的壓縮過程也能夠設置一個合適的百分比來控制大小。
多張圖片的使用中,請注意流的flush與close(我沒有及時flush和close的時候也執(zhí)行正確了,這個有待研究一下,可是為了保證一個良好的習慣還是注意下吧)。
?
5.關于options方法
網(wǎng)上還有非常多文章用BitmapFactory.Options來作為decodeStream時候的一個參數(shù),這個我臨時沒有詳細實驗過,哪位朋友實驗過了能夠回復交流哈
總結
以上是生活随笔為你收集整理的Android加载图片OOM错误解决方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于verilog的FFT设计与实现
- 下一篇: Android工程的编译过程