做android開發(fā)最揪心的就是遇到OOM棘街,為什么呢蟆盐?因?yàn)樗皇窃诰幾g期就報(bào)異常承边,是在運(yùn)行期才報(bào)異常,而且它是積累性的石挂,一次兩次運(yùn)行還不一定能重現(xiàn)博助,你要找出問(wèn)題所在也不容易。但是基本可以肯定痹愚,在加載大量圖片或一張分辨率很高的圖片時(shí)富岳,很容易出現(xiàn)OOM(內(nèi)存溢出)。
我碰到的這個(gè)OOM是在驗(yàn)證手勢(shì)密碼的頁(yè)面拯腮,因?yàn)檫@個(gè)頁(yè)面會(huì)被經(jīng)常打開窖式,而不是只打開一兩次,所以就滿足了OOM發(fā)生的條件动壤。在這個(gè)頁(yè)面加載的背景圖太大萝喘,在某些型號(hào)的手機(jī)上容易出現(xiàn)OOM。
這段代碼是官方的解決方案琼懊,可以放心的用:
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
使用的時(shí)候把屏幕的寬高傳入(因?yàn)槲业倪@張圖片是填充屏幕的背景圖阁簸,所以以屏幕寬高設(shè)置,其他情況根據(jù)imageView的寬高設(shè)定):
bgBitmap = ImageUtil.decodeSampledBitmapFromResource(getResources(), R.mipmap.gesture_bg,
ViewUtil.getScreenWidth(this), ViewUtil.getScreenHeight(this));
iv_bg.setImageBitmap(bgBitmap);
不用時(shí)注意銷毀bitmap:
@Override
protected void onDestroy() {
super.onDestroy();
if(iv_bg != null){
iv_bg.setImageBitmap(null);
}
if(bgBitmap != null){
bgBitmap.recycle();
bgBitmap = null;
}
if (mGestureContentView != null) {
mGestureContentView.destroyBitmap();
}
}
所占用的內(nèi)存前后對(duì)比:
改前:
改后: