当前位置:操作系统 > 安卓/Android >>

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

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

 

 
补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,