Android加载大图片时的OOM异常及解决(图片的二次采样)

今天在加载大图时出现了内存溢出异常,后面通过二次采样的方法解决了该异常。

图片的二次采样是为了避免加载图片时,出现OOM异常。
OOM(OutOfMemory)就是内存溢出,即Out Of Memory。也就是说内存占有量超过了VM所分配的最大内存。
android在内存中,只会开辟出当前屏幕大小的位图的大小的四倍的空间。当我们去解析一张图片时,如果图片太大就会造成OOM,这时我们就可以对该图片通过二次采样生成缩略图。设置它的缩放比例inSampleSize去解决。但我们要如何去获取这个缩放比呢?
获取缩放比步骤:

  1. 获取当前图片宽高
  2. 通过图片的宽高分别和控件的宽高(我这里控件的宽高是传递过来的)进行计算获得到相应的宽高缩放比。

通过图片二次采样解决方法如下:
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);
            }
        });

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值