高效使用bitmaps有什麼好處?
我們常常提到的「android程式優化」,通常指的是效能和記憶體的優化,即:更快的響應速度,更低的記憶體占用。android程式的效能和記憶體問題,大部分都和緊密相關,而的載入在很多情況下很用到bitmap(位圖)這個類。而由於bitmap自身的特性(將每個畫素的屬性全部儲存在記憶體中),導致稍有不慎就會建立出乙個占用記憶體非常大的bitmap物件,從而導致載入過慢,還會有記憶體溢位的風險。所以,android程式要做優化,bitmap的優化是必不可少的一步。
需要對bitmap進行優化
的情形
首先請看一行**: ?
1mimageview.setimageresource(r.drawable.my_image);
這是一行從資源檔案中載入到imageview的**。通常這段**沒什麼問題,但有些情況下,你需要對這段**進行優化。例如當的尺寸遠遠大於imageview的尺寸時,或者當你要在乙個listview或gridview中批量載入一些大小未知的時。實際上,以上這行**會在執行時使用bitmapfactory.decodestream()方法將資源生成乙個bitmap,然後由這個bitmap生成乙個drawable,最後再將這個drawable設定到imageview。由於在過程中生成了bitmap,因此如果你使用的過大,就會導致效能和記憶體占用的問題。另外,需要優化的情形不止這一種,這裡就不再列舉。
下面分步說明使用**來減小bitmap的尺寸從而達到減小記憶體占用的方法:
1. 獲取原尺寸
通常,我們使用bitmapfactory.decoderesource()方法來從資源檔案中讀取一
張並生成乙個bitmap。但如果使用乙個bitmapfactory.options物件,並把該物件的injustdecodebounds屬性設定為true,decoderesource()方法就不會生成bitmap物件,而僅僅是讀取該的尺寸和型別資訊:
? 1
2
3
4
5
6
bitmapfactory.options options =
new
bitmapfactory.options();
options.injustdecodebounds =
true
;
bitmapfactory.decoderesource(getresources(), r.id.myimage, options);
int
imageheight = options.outheight;
int
imagewidth = options.outwidth;
string imagetype = options.outmimetype;
2. 根據原圖尺寸和目標區域的尺寸計算出合適的bitmap尺寸
bitmapfactory.options類有乙個引數insamplesize,該引數為int型,他的值指示了在解析為bitmap時在長寬兩個方向上畫素縮小的倍數。insamplesize的預設值和最小值為1(當小於1時,解碼器將該值當做1來處理),且在大於1時,該值只能為2的冪(當不為2的冪時,解碼器會取與該值最接近的2的冪)。例如,當insamplesize為2時,乙個2000*1000的,將被縮小為1000*500,相應地,它的畫素數和記憶體占用都被縮小為了原來的1/4: ?
12
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public
static
int
calculateinsamplesize(
bitmapfactory.options options,
int
reqwidth,
int
reqheight)
}
return
insamplesize;
}
3. 根據計算出的insamplesize生成bitmap ?
12
3
4
5
6
7
8
9
10
11
12
13
14
15
public
static
bitmap decodesampledbitmapfromresource(resources res,
int
resid,
int
reqwidth,
int
reqheight)
這裡有一點要注意,就是要在第二遍decode之前把injustdecodebounds設定回false。
4. 呼叫以上的
decodesampledbitmapfromresource方法,使用自定尺寸的bitmap。
如果你要將一張大圖設定為乙個100*100的縮圖,執行以下**: ?
1mimageview.setimagebitmap(decodesampledbitmapfromresource(getresources(), r.id.myimage,
100
,
100
));
到此,使用decoderesource()方法將乙個大**析為小尺寸bitmap的應用就完成了。同理,還可以使用decodestream(),decodefile()等方法做相同的事,原理是一樣的。
延伸:乙個bitmap到底占用多大記憶體?系統給每個應用程式分配多大記憶體?
· bitmap占用的記憶體為:畫素總數 * 每個畫素占用的記憶體。在android中,bitmap有四種畫素型別:argb_8888、argb_4444、argb_565、alpha_8,他們每個畫素占用的位元組數分別為4、2、2、1。因此,乙個2000*1000的argb_8888型別的bitmap占用的記憶體為2000*1000*4=8000000b=8mb。
· android根據裝置螢幕尺寸和dpi的不同,給系統分配的單應用程式記憶體大小也不同,具體如下表(**取自android 4.4 compatibility definition document (cdd)):
螢幕尺寸
dpi應用記憶體
small / normal / large
ldpi / mdpi
16mb
small / normal / large
tvdpi / hdpi
32mb
small / normal / large
xhdpi
64mb
small / normal / large
400dpi
96mb
small / normal / large
xxhdpi
128mb
xlarge
mdpi
32mb
xlarge
tvdpi / hdpi
64mb
xlarge
xhdpi
128mb
xlarge
400dpi
192mb
xlarge
xxhdpi
256mb
Bitmap的高效載入
如何高效的載入乙個bitmap,這是乙個很有意義的話題,因為在我們開發的過程中,經常會遇到這樣錯誤 outofmemoryerror 這樣的錯誤,很多時候都是因為載入bitmap出現的記憶體溢位.如何載入乙個bitmap bitmap在andriod中指的是一張,那麼如何載入乙個?bitmapfac...
Bitmap的載入和Cache
載入bitmap bitmapfactory decodefile decoderesource decodestream decodebytearray 高效載入bitmap的核心思想 採用bitmapfactory.options,使用insamplesize 取樣率 引數來縮放 若為1則取樣後...
Bitmap的載入與快取
android系統中一般用bitmap物件表示,它支援png,jpg等常見格式。通常情況下的體積都比較大,單個應用允許使用的記憶體又是有限的,所以我們需要採取一些手段減少記憶體占用並提高載入速度。假設我們用imageview顯示,通常它的尺寸要比的尺寸小很多,那麼把整個載入進記憶體顯然是沒有必要的。...