Bitmap
1.Bitmap使用需要注意哪些問題耀鸦?
- 參考回答:
- 要選擇合適的圖片規(guī)格(bitmap類型):通常我們優(yōu)化Bitmap時技肩,當(dāng)需要做性能優(yōu)化或者防止OOM并闲,我們通常會使用RGB_565,因?yàn)锳LPHA_8只有透明度玩裙,顯示一般圖片沒有意義,Bitmap.Config.ARGB_4444顯示圖片不清楚晰绎,Bitmap.Config_ARGB_8888占用內(nèi)存最多。
- ALPHA_8每個像素占用1byte內(nèi)存
- ARGB_4444每個像素占用2byte內(nèi)存
- ARGB_8888每個像素占用4byte內(nèi)存(默認(rèn))
- ARGB_565每個像素占用2byte內(nèi)存
- 降低采樣率:BitmapFactory.Options 參數(shù)inSampleSize的使用括丁,先把option.inJustDecodeBounds設(shè)為true荞下,只是去讀取圖片的大小,在拿到圖片的大小之后和要顯示的大小做比較通過calculateInSampleSize()函數(shù)計(jì)算inSampleSize的具體值,得到值之后尖昏。option.inJustDecodeBounds設(shè)為false讀圖片資源仰税。
- 復(fù)用內(nèi)存:即通過軟引用(內(nèi)存不夠的時候才會回收掉),復(fù)用內(nèi)存塊抽诉,不需要再重新給這個bitmap申請一塊新的內(nèi)存陨簇,避免了一次內(nèi)存的分配和回收,從而改善運(yùn)行效率迹淌。
- 使用recycle()方法及時回收內(nèi)存河绽。
- 壓縮圖片。
- 要選擇合適的圖片規(guī)格(bitmap類型):通常我們優(yōu)化Bitmap時技肩,當(dāng)需要做性能優(yōu)化或者防止OOM并闲,我們通常會使用RGB_565,因?yàn)锳LPHA_8只有透明度玩裙,顯示一般圖片沒有意義,Bitmap.Config.ARGB_4444顯示圖片不清楚晰绎,Bitmap.Config_ARGB_8888占用內(nèi)存最多。
2唉窃、Bitmap.recycle()會立即回收么耙饰?什么時候會回收?如果沒有地方使用這個Bitmap纹份,為什么垃圾回收不會直接回收苟跪?
參考回答:
- 通過源碼可以了解到,加載Bitmap到內(nèi)存里以后矮嫉,是包含兩部分內(nèi)存區(qū)域的削咆。簡單的說,一部分是java部分的蠢笋,一部分是C部分的拨齐。這個Bitmap對象是由Java部分分配的,不用的時候系統(tǒng)就會自動回收了昨寞。
- 但是那個對應(yīng)的C可用的內(nèi)存區(qū)域瞻惋,虛擬機(jī)是不能直接回收的,這個只能調(diào)用一下系統(tǒng)的垃圾回收器進(jìn)行回收援岩,調(diào)用System.gc()并不能保證立即開始進(jìn)行回收過程歼狼,而只是為了加快回收的到來。
3享怀、一張Bitmap所占用內(nèi)存以及內(nèi)存占用的計(jì)算
參考回答:
- Bitmap所占內(nèi)存大小 = 寬度像素 X (inTargetDensity / inDensity) X 高度像素 X (inTargetDensity / inDensity) X 一個像素所占的內(nèi)存字節(jié)大小羽峰。
- 注:這里inDensity表示圖標(biāo)圖片的dpi(放在哪個資源文件下),inTargetDensity表示目標(biāo)屏幕的dpi,所以你可以發(fā)現(xiàn)inDensity 和 inTargetDensity會對Bitmap的寬高進(jìn)行拉伸添瓷,進(jìn)而改變Bitmap占用內(nèi)存大小梅屉。
- 在Bitmap 里有兩個獲取內(nèi)存占用大小的方法。
- getByteCount(): API12 加入鳞贷,代表存儲Bitmap 的像素需要的最小內(nèi)存坯汤。
- getAllocationByteCount():API19 加入,代表在內(nèi)存中為 Bitmap 分配的內(nèi)存大小搀愧,代替了getByteCount()方法惰聂。
- 在不復(fù)用Bitmap時疆偿,getByteCount()和getAllocationByteCount返回結(jié)果是一樣的。在通過復(fù)用Bitmap來解碼圖片時搓幌,那么getByteCount()表示新解碼圖片占用內(nèi)存的大小杆故,getAllocationByteCount()表示被復(fù)用Bitmap真實(shí)占用內(nèi)存的大小。
4.Android中緩存更新策略鼻种?
參考回答:
- Android 的緩存更新策略沒有統(tǒng)一的標(biāo)準(zhǔn)反番,一般來說,緩存策略主要包含緩存的添加叉钥、獲取和刪除這三類操作罢缸,但不管是內(nèi)存緩存還是存儲設(shè)備緩存,他們緩存容量是有限制的投队,因此刪除一些舊緩存并添加新緩存枫疆,如何定義緩存的新舊就是一種策略,不同策略就對應(yīng)不同的緩存算法敷鸦。
- 比如簡單地根據(jù)文件的最后修改時間來定義緩存的新舊息楔,當(dāng)緩存滿時就將最后修改時間較早的緩存移除,這就是一種緩存算法扒披,但不算很完美值依。
5、LRU的原理碟案?
參考回答:
- 為減少流量消耗愿险,可采用緩存策略。常用的緩存算法是LRU(least Recently Used):當(dāng)緩存滿時价说,會優(yōu)先淘汰那些近期最少使用的緩存對象辆亏。主要是兩種方式:
- LruCache(內(nèi)存緩存):LruCache類是一個線程安全的泛型類:內(nèi)部采用一個LinkedHashMap以強(qiáng)引用的方式存儲外界的緩存對象,并提供get和put方法來完成緩存的獲取和添加操作鳖目,當(dāng)緩存滿時會移除早使用的緩存對象扮叨,再添加新的緩存對象。
- DiskLruCache(磁盤緩存):通過將緩存對象寫入文件系統(tǒng)從而實(shí)現(xiàn)緩存效果