解决setImageResource()内存溢出

尽量不要直接使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过Java层的createBitmap来完成的,需要消耗更多内存。 

因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。

如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常

另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应, 使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。 


通过以下代码就可以避免OOM,然后将返回的bitmap设置给view

/** * 将图片资源转为BitmapDrawable * @param imageID * @return */ private BitmapDrawable createBitmapDrawable(int imageID){ InputStream is = null; try{ Log.d(Utils.TAG, "Begin createBitmapDrawable"); BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = true; is = getResources().openRawResource(imageID); //decodeStream直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,节省了java层的空间 Bitmap bm = BitmapFactory.decodeStream(is, null, opt); BitmapDrawable bd = new BitmapDrawable(getResources(), bm); Log.d(Utils.TAG, "finish createBitmapDrawable---BitmapDrawable " + bd==null?"==null":"!=null"); return bd; }finally{ try { if(is != null){ is.close(); is = null; } } catch (IOException e) { e.printStackTrace(); } } }

你可能感兴趣的:(解决setImageResource()内存溢出)