今天在加载大图时出现了内存溢出异常,后面通过二次采样的方法解决了该异常。
图片的二次采样是为了避免加载图片时,出现OOM异常。
OOM(OutOfMemory)就是内存溢出,即Out Of Memory。也就是说内存占有量超过了VM所分配的最大内存。
android在内存中,只会开辟出当前屏幕大小的位图的大小的四倍的空间。当我们去解析一张图片时,如果图片太大就会造成OOM,这时我们就可以对该图片通过二次采样生成缩略图。设置它的缩放比例inSampleSize去解决。但我们要如何去获取这个缩放比呢?
获取缩放比步骤:
- 获取当前图片宽高
- 通过图片的宽高分别和控件的宽高(我这里控件的宽高是传递过来的)进行计算获得到相应的宽高缩放比。
通过图片二次采样解决方法如下:
1、创建BitmapUtils工具类
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
* Created by Timeless_Lin on 2016/9/19.
*/
public class BitmapUtils {
public static Bitmap getBitmap(Context mContext, int width, int height) {
//1.获取option
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
//2.开始解析图片边缘
BitmapFactory.decodeResource(mContext.getResources(), R.drawable.oom, opt);
//3.拿到图片的宽高
int imgWidth = opt.outWidth;
int imgHeight = opt.outHeight;
//4.计算缩放比
int scaleX = (int) Math.ceil(imgWidth / width);
int scaleY = (int) Math.ceil(imgHeight / height);
//5.设置图片质量及缩放比
opt.inPreferredConfig = Bitmap.Config.ALPHA_8;
opt.inSampleSize = Math.max(scaleX,scaleY);
//6.返回并再次解析图片
opt.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(mContext.getResources(),R.drawable.oom,opt);
}
}
2、直接在相应位置调用上面的工具类就可以了
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
iv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
//布局改变时调用该方法
@Override
public void onGlobalLayout() {
//获取控件的宽高
int width = iv.getWidth();
int height = iv.getHeight();
Bitmap bitmap = BitmapUtils.getBitmap(MainActivity.this,width,height);
//加载缩放结果的bitmap
iv.setImageBitmap(bitmap);
//移除监听(防止多次调用该方法)
iv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
}