首先,您需要了解一下,图片占用内存的计算方法,传送门:http://blog.csdn.net/scry5566/article/details/11568751
尽量不要使用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中配置相应的图片资源,
否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。
下面附上我个人写代码:
/** * Funciton:按指定长宽并以最省内存的方式读取本地资源的图片(通过C层API加载图片,消耗的是C层内存,而不会消耗JAVA虚拟机的内存)。 * <font color="red">【注意】此方法应该在以下非常情况下使用:应用内存非常吃紧或者图片过大时可使用此方法。 * 使用此方法的可能后果:会有一定几率造成应用崩溃,请慎用,</font> * * @param context * @param resId * @return */ public static Bitmap decodeStreamWithLowMemory(Context context, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(context.getResources(), resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; // Bitmap.Config.ALPHA_8,Bitmap.Config.ARGB_4444,Bitmap.Config.RGB_565 // 设置这几个参数效果都差不多,确实相当省内存啊,而且还跟原图清晰度相当 options.inPreferredConfig = Bitmap.Config.ARGB_8888; options.inPurgeable = true; options.inInputShareable = true; // 获取资源图片 InputStream is = context.getResources().openRawResource(resId); return BitmapFactory.decodeStream(is, null, options); }
/** * Funciton:以最省内存的方式读取本地资源的图片; <font color="red">【注意】: * 此方法以BitmapFactory.decodeResource ()去加载图片,使用此方法每次会创建一个新的Btimap对象, * 而不会共享应用res中创建的Btimap资源,因此要即时回收旧图片,以免造成内存泄露。</font> * * @param context * @param resId * @return */ public static Bitmap decodeResourceWithLowMemory(Context context, int resId) { BitmapFactory.Options opt = new BitmapFactory.Options(); // Bitmap.Config.ALPHA_8,Bitmap.Config.ARGB_4444,Bitmap.Config.RGB_565 // 设置这几个参数效果都差不多,确实相当省内存啊,而且还跟原图清晰度相当 opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = true; // return BitmapFactory.decodeResource(context.getResources(), resId, opt); }