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


             首先,您需要了解一下,图片占用内存的计算方法,传送门: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);
    	}




  • 相关阅读:
    Ubuntu创建VLAN接口配置
    Ubuntu配置网桥方法
    Ubuntu重启网卡的三种方法
    kvm存储池和存储卷
    ubuntu如何切换到root用户
    修改Ubuntu默认apt下载源
    Java之泛型<T> T与T的用法(转载)
    Java关键字(一)——instanceof(转载)-BeanCopier相关
    java代码之美(12)---CollectionUtils工具类(转载)
    Lombok-注解@Slf4j的使用
  • 原文地址:https://www.cnblogs.com/james1207/p/3315355.html
Copyright © 2020-2023  润新知