Android有效解决加载大图片时内存溢出的问题

来源:互联网 发布:mac字体下载少女体 编辑:程序博客网 时间:2024/06/11 23:41

         首先,您需要了解一下,图片占用内存的计算方法,传送门: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 dimensionsBitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(context.getResources(), resId, options);// Calculate inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);// Decode bitmap with inSampleSize setoptions.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);}