[Android] Bitmap OOM解决办法三

本文介绍了在Android开发中遇到的OOM问题及多种解决方案,包括图片边界压缩、动态内存回收、优化Dalvik虚拟机堆内存分配等,并提供了具体的代码示例。

在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,
常用的解决方案如下几种:
  一:在内存中加载图片时直接在内存中做处理,如:边界压缩
  二:动态回收内存

三:优化Dalvik虚拟机的堆内存分配
  四:自定义堆内存大小

使用边界压缩的情况下间接的使用了软引用来避免OOM

private Map> map = new HashMap>();
      public void getBitmap(String path) {
            Options bitmapFactoryOptions = new BitmapFactory.Options();
             // 下面这个设置是将图片边界不可调节变为可调节
            bitmapFactoryOptions. inJustDecodeBounds = true;
            bitmapFactoryOptions. inSampleSize = 5;
                     Bitmap bitmap1 = BitmapFactory. decodeFile(path, bitmapFactoryOptions);
            int outWidth = bitmapFactoryOptions. outWidth;
            int outHeight = bitmapFactoryOptions. outHeight;
            float imagew = 150;
            float imageh = 150;
            int yRatio = ( int) Math. ceil(outHeight / imageh);
            int xRatio = ( int) Math. ceil(outWidth/ imagew);
            if (yRatio > 1 || xRatio > 1) {
                  if (yRatio > xRatio) {
                       bitmapFactoryOptions. inSampleSize = yRatio;
                 } else {
                       bitmapFactoryOptions. inSampleSize = xRatio;
                 }
           }
           bitmapFactoryOptions. inJustDecodeBounds = false;
           Bitmap  bitmap = BitmapFactory. decodeFile(path, bitmapFactoryOptions);
            //软引用
           SoftReference srf = new SoftReference(bitmap );
            map.put(path, srf);
     }

使用边界压缩的情况下间接的使用了软引用来避免OOM,但大家都知道,这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存,如果图片多且大,这种方式还是会引用OOM异常。
可以采用下面更测底的方式避免OOM:
public static Bitmap readBitMap(Context context, int resId) {
           BitmapFactory.Options opt = new BitmapFactory.Options();
           opt. inPreferredConfig = Bitmap.Config. RGB_565;
           opt. inPurgeable = true;
           opt. inInputShareable = true;
            // 获取资源图片
           InputStream is = context.getResources().openRawResource(resId);
            return BitmapFactory. decodeStream(is, null, opt);
}
//显式调用GC来回收内存
if (bitmap .isRecycled()== false){
         bitmap.recycle();
        System.gc ();
}

对于Android平台来说,其托管层使用的Dalvik JavaVM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用 dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体 原理我们可以参考开源工程,这里我们仅说下使用方法: 代码如下:
private final static float TARGET_HEAP_UTILIZATION = 0.75f;
VMRuntime.getRuntime().setTargetHeapUtilization( TARGET_HEAP_UTILIZATION );

自定义我们的应用需要多大的内存,这个好暴力哇,强行设置最小内存大小,代码如下:
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
//设置最小heap内存为6MB大小
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);


转载于:https://my.oschina.net/u/242041/blog/198666

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值