介紹
Android開發(fā)應(yīng)用過程中加載bitmap是很tricky的,如果你稍微不注意,bitmaps就會快速消耗光應(yīng)用的可用內(nèi)存,導(dǎo)致應(yīng)用奔潰,拋出OutofMemoryError異常,俗稱OOM:
java.lang.OutofMemoryError: bitmap size exceeds VM budget.
而這主要有幾個原因:
- Android設(shè)備給每個應(yīng)用分配的可用內(nèi)存為16M,但是這個值因機型而異(下面有獲取分配內(nèi)存大小的方法),現(xiàn)在的很多機子分配的limit都高出很多了,對于應(yīng)用來說,要將使用的內(nèi)存控制在這個limit以內(nèi).
- Bitmap會占用大量內(nèi)存尤其是照片,比如5百萬像素的攝像頭拍的照片大小為2592x1936 pixels, 如果bitmap的配置使用ARGB_8888(Android 2.3以后的默認(rèn)值),那么加載一張照片就占用了將近19M的內(nèi)存(2592*1936*4 bytes),瞬間就將應(yīng)用的內(nèi)存limit消耗光了,特別是內(nèi)存limit較小的設(shè)備.
- Android應(yīng)用的一些UI組件經(jīng)常需要一次性加載多張bitmaps,比如ListView,GridView和ViewPager.
官網(wǎng)提供的五個教學(xué)課程來加載Bitmap
- Loading Large Bitmaps Efficiently
- Processing Bitmaps Off the UI Thread
- Caching Bitmaps
- Managing Bitmap Memory
- Displaying Bitmaps in Your UI
Bitmap.Config的具體配置如下表:
Bitmap.Config | Description |
---|---|
ALPHA_8 | Each pixel is stored as a single translucency (alpha) channel |
ARGB_4444 | This field was deprecated in API level 13. Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead. |
ARGB_8888 | Each pixel is stored on 4 bytes. |
RGB_565 | Each pixel is stored on 2 bytes and only the RGB channels are encoded: red is stored with 5 bits of precision (32 possible values), green is stored with 6 bits of precision (64 possible values) and blue is stored with 5 bits of precision. |
獲取應(yīng)用分配的最大內(nèi)存大小的方法:
- Runtime的maxMemory()方法返回bytes
- ActivityManager的getMemoryClass()方法返回megabytes
例:
// get max memory by runtime
long maxBytes=Runtime.getRuntime().maxMemory();
Log.i("Log","maxMemory: "+maxBytes/1024/1024+" M");
// get max memory by activity manager
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int maxMemory = activityManager.getMemoryClass();
Log.i("Log","memClass: "+maxMemory+" M");
結(jié)果輸出:
Log: maxMemory: 256 M
Log: memClass: 256 M