您的位置:首页 > 移动开发 > Android开发

Android之读取大图片内存溢出

2015-08-14 11:43 405 查看
在工作的过程中,相信很多朋友会遇到读取本地图片,由于图片过大,报出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);
};
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: