Android之读取大图片内存溢出

在工作的过程中,相信很多朋友会遇到读取本地图片,由于图片过大,报出outOfMemory的错误,导致crash。

那是因为大部分朋友都是通过setImageBitmap或setImageResource或BitmapFactory.decodeResource或BitmapFactory.decodeFile来设置图片,

这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。 
因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source, 
decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode, 
无需再使用java层的createBitmap从而节省了java层的空间 
如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常 
另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应, 
使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源, 
否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了

下面看代码

private void getBitmap1() {
		// 1.会导致内存溢出
		Bitmap bitmap = null;
		bitmap = BitmapFactory.decodeFile(path);
		imageView.setImageBitmap(bitmap);
		bitmap.recycle();
	}

	private void getBitmap2() {
		// 2.会导致内存溢出
		imageView
				.setImageDrawable(getResources().getDrawable(R.drawable.world));

	}

	private void getBitmap3() {
		// 3.不会导致内存溢出
		InputStream is = getResources().openRawResource(R.drawable.world);
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = false;
		options.inSampleSize = 10; // width,hight设为原来的十分一
		Bitmap btp = BitmapFactory.decodeStream(is, null, options);
		imageView.setImageBitmap(btp);
		btp.recycle();

	}

	private void getBitmap4() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				// 4.不会导致内存溢出
				Bitmap bitmap = null;
				File file = new File(path);
				InputStream is = null;
				try {
					is = new FileInputStream(file);
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				// bitmap = BitmapFactory.decodeStream(is);
				BitmapFactory.Options opt = new BitmapFactory.Options();
				opt.inPreferredConfig = Bitmap.Config.RGB_565;
				opt.inPurgeable = true;
				opt.inInputShareable = true;
				opt.inSampleSize = 10;
				bitmap = BitmapFactory.decodeStream(is, null, opt);
				Message msg = new Message();
				msg.obj = bitmap;
				handler.sendMessage(msg);
				// imageView.setImageBitmap(bitmap);
				// bitmap.recycle();
			}
		}) {
		}.start();

	}

	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			imageView.setImageBitmap((Bitmap) msg.obj);
		};
	};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值