Bitmap的管理
與圖片有關(guān)的軟件免不了要做Bitmap的管理,要不然很可能就會發(fā)生OutOfMemory(OOM)的錯誤,致使程序崩潰。引起這種現(xiàn)象的原因無非是:
1.長期保持對某個對象或數(shù)據(jù)的引用,導(dǎo)致java的垃圾回收器不能回收不再使用的內(nèi)存空間;
2.正在使用的有效對象占用內(nèi)存空間大,導(dǎo)致多個有效對象生成時,吃完程序所分配的內(nèi)存;
一般會報這種錯誤:java.lang.OutOfMemoryError: bitmap size exceeds VM budget,這是因為,android系統(tǒng)中讀取位圖Bitmap時.分給虛擬機中圖片的堆棧大小只有8M。所以不管是如何調(diào)用的圖片,太多太大虛擬機肯定會報這個錯誤。(對于實際的機器來說,這個內(nèi)存分配是不是很大?)
而像相冊這樣子的應(yīng)用,最好的效果是:
1)將圖片(單個資源)縮小到適當(dāng)?shù)拇笮?#xff0c;以便于同時加載多張圖片;
2)就算縮小到適當(dāng)?shù)拇笮?#xff0c;我們也不能將所有圖片的引用同時保存在內(nèi)存中,這時候需要將部分的圖片釋放;
遇到這種問題的解決方案是:縮小圖片+回收資源的方式,來優(yōu)化內(nèi)存:
盡量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource來設(shè)置一張大圖,因為這些函數(shù)在完成decode后,最終都是通過java層的createBitmap來完成的,需要消耗更多內(nèi)存。因此,改用先通過BitmapFactory.decodeStream方法,創(chuàng)建出一個bitmap,再將其設(shè)為ImageView的 source,decodeStream最大的秘密在于其直接調(diào)用JNI>>nativeDecodeAsset()來完成decode,無需再使用java層的createBitmap,從而節(jié)省了java層的空間。如果在讀取時加上圖片的Config參數(shù),可以更有效減少加載的內(nèi)存,從而更有效阻止拋out of Memory異常。
另外,decodeStream直接拿的圖片來讀取字節(jié)碼了, 不會根據(jù)機器的各種分辨率來自動適應(yīng),使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相應(yīng)的圖片資源,否則在不同分辨率機器上都是同樣大小(像素點數(shù)量),顯示出來的大小就不對了。
1)縮小圖片的方式:
InputStream is = this.getResources().openRawResource(R.drawable.pic1); BitmapFactory.Options options=new BitmapFactory.Options(); options.inJustDecodeBounds = false; options.inSampleSize = 10; //width,hight設(shè)為原來的十分一 Bitmap btp =BitmapFactory.decodeStream(is,null,options);2)回收圖片的方式:
if(!bmp.isRecycle() ){bmp.recycle() //回收圖片所占的內(nèi)存system.gc() //提醒系統(tǒng)及時回收 }緩存:加載圖片的時候首先檢測是否被緩存然后再去動作
//用來存放圖片的緩存HashMap<Integer, Bitmap> bitmapCache = new HashMap<Integer, Bitmap>();//如果沒有圖片,或者已經(jīng)存在if(bitmapCache.isEmpty() || !AppConst.bitmapCache.containsKey(position)){bitmapCache.put(position, bm);System.out.println("-----------inset cache---------");}定義FreeBitmap函數(shù),在activity結(jié)束的時候,調(diào)用FreeBitmap函數(shù),回收map中的資源
private void FreeBitmap(HashMap<Integer, Bitmap> cache){if(cache.isEmpty()){return;}for(Bitmap bitmap:cache.values()){if(bitmap != null && !bitmap.isRecycled()){bitmap.recycle();System.out.println("=============recycle bitmap=======");}}cache.clear();}轉(zhuǎn)載于:https://blog.51cto.com/cfy10/1325174
總結(jié)
- 上一篇: MongoDB实战(4)MapReduc
- 下一篇: 位运算及在java中的应用整理