android 减少图片出现oom错误

在做Android图片程序的时候,由于图片比较多,很有很的机会出现OOM的机会,根据网上的资料做了些总结,期待能够减少OOM出现的机会。

1.使用底层的方法来替代使用java层的方法

         尽量不要使用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中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。 另外,以下方式也大有帮助:

片段一: 

[java] view
plain
copy

  1. InputStream is = this.getResources().openRawResource(R.drawable.pic1);   
  2.      BitmapFactory.Options options=new BitmapFactory.Options();   
  3.      options.inJustDecodeBounds = false;   
  4.      options.inSampleSize = 10;   //width,hight设为原来的十分一   
  5.      Bitmap btp =BitmapFactory.decodeStream(is,null,options);   

片段二:

[java] view
plain
copy

  1. if(!bmp.isRecycle() ){   
  2.          bmp.recycle()   //回收图片所占的内存   
  3.          system.gc()  //提醒系统及时回收   
  4. }   

片段三:

[java] view
plain
copy

  1. public static Bitmap readBitMap(Context context, int resId){    
  2.      BitmapFactory.Options opt = new BitmapFactory.Options();    
  3.          opt.inPreferredConfig = Bitmap.Config.RGB_565;     
  4.        opt.inPurgeable = true;    
  5.        opt.inInputShareable = true;     
  6.       InputStream is = context.getResources().openRawResource(resId);    
  7.         return BitmapFactory.decodeStream(is,null,opt);    
  8.   }   

2. 优化虚拟机的堆内存使用

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

  private final static float TARGET_HEAP_UTILIZATION = 0.75f; 

在程序onCreate时就可以调用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。 

Android堆内存也可自己定义大小 
   
对于一些Android项目,影响性能瓶颈的主要是Android自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对性能的影响十分敏感,除了 优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的对内存大小,我们使用Dalvik提供的 dalvik.system.VMRuntime类来设置最小堆内存为例: 
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ; 

VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。

当然对于内存吃紧来说还可以通过手动干涉GC去处理 

    3.其他一些使用技巧

       1.不同大小的图片需要做成同一个高度的的缩略图(如100px),而且要保证图片不失真,那怎么办?我们总不能将原始图片加载到内存中再进行缩放处理吧,要知道在移动开发中,内存是相当宝贵的,而且一张100K的图片,加载完所占用的内存何止100K?

   经过研究,发现,Options中有个属性inJustDecodeBounds,研究了一下,终于明白是什么意思了,SDK中的E文是这么说的
      If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.
  意思就是说如果该值设为true那么将不返回实际的bitmap不给其分配内存空间而里面只包括一些解码边界信息即图片大小信息,那么相应的方法也就出来了,通过设置inJustDecodeBounds为true,获取到outHeight(图片原始高度)和 outWidth(图片的原始宽度),然后计算一个inSampleSize(缩放值),然后就可以取图片了,这里要注意的是,inSampleSize 可能小于0,必须做判断。

            2.用BitmapFactory解码一张图片时,有时会遇到该错误。这往往是由于图片过大造成的。要想正常使用,则需要分配更少的内存空间来存储。
BitmapFactory.Options.inSampleSize.设置恰当的inSampleSize可以使BitmapFactory分配更少的空间以消除该错误。inSampleSize的具体含义请参考SDK文档。例如:

[java] view
plain
copy

  1. BitmapFactory.Options opts = new BitmapFactory.Options();   
  2. opts.inSampleSize = 4;  
  3. Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);   

设置恰当的inSampleSize是解决该问题的关键之一。

时间: 2024-10-02 05:12:21

android 减少图片出现oom错误的相关文章

android clean时出现错误

问题描述 android clean时出现错误 项目没有问题,项目用过引用过了4个库, 求解??? Errors occurred during the build.Errors running builder 'Android Package Builder' on project 'android-support-v7-appcompat'.Problems encountered while deleting resources.Could not delete 'D:workspacea

android studio的这个错误怎么解决???

问题描述 android studio的这个错误怎么解决??? Error:Execution failed for task ':app:transformClassesWithInstantRunForDebug'. java.lang.ClassNotFoundException: io.rong.imlib.model.UserInfo 解决方案 Gradle: Execution failed for task ':processDebugManifest' ?http://stack

接口-com.android.volley.ServerError 这个错误是怎么回事

问题描述 com.android.volley.ServerError 这个错误是怎么回事 如题所示,安卓调用接口,网页访问都是正常,但是在安卓端就报这个错误,求解! 解决方案 您好 ,我也遇到一样的问题,请问您当初是怎么解决的?? 解决方案二: 我应该不是楼上的问题,题主的问题是什么呢? 解决方案三: 你访问得到的对象是jsonobject但是你是用jsarray请求的 解决方案四: 楼主的问题解决了没有,表示也遇到了同样的问题? 解决方案五: 服务器端错误啊,应该是服务器端的问题.跟网页请求

oom-编译android程序出现OOM

问题描述 编译android程序出现OOM 使用 jdk-7u79-windows-x64,android 5.0.1,IntelliJ IDEA Community Edition 14.0.2编译程序,出现OOM: Error:Android Dex: java.lang.OutOfMemoryError: GC overhead limit exceeded Error:Android Dex: at java.util.BitSet.initWords(BitSet.java:164)

Android java代码有错误,获取的list一直为0,问题出在哪里

问题描述 Android java代码有错误,获取的list一直为0,问题出在哪里 package com.example.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.content.Intent; import android.content.

android studio自定义方法出现错误

问题描述 android studio自定义方法出现错误 例如我创建的每个方法都会有小波浪线 这个要怎么办??上面的类文件还有红色的波浪线,我发现出问题的都是自己创建的方法android studio不能识别..怎么解决这样的问题??? 解决方案 用http://www.jb51.net/softjc/408173.html 的方法创建下看看检查是否有重名或者别的错误

大侠,android studio出现这个错误怎么解决!?

问题描述 大侠,android studio出现这个错误怎么解决!? 解决方案 资源没有找到,看下资源文件 解决方案二: Android Studio错误Android Studio 运行时出现的错误及解决办法关于android studio启动时加载项目gradle build出现错误的解决方法 解决方案三: 看起来像是v7包报错了,重新创建一个项目试试. 解决方案四: android对应的API版本的问题 解决方案五: V7包没有找到或V7包版本太低了

opencv for android 安装sdk出现错误

问题描述 opencv for android 安装sdk出现错误 小白刚接触,按教程装的,总是出现这种错误. 解决方案 楼主.图片挂了...

移动开发-Android应用设置密码登录错误

问题描述 Android应用设置密码登录错误 package com.example.broadbestpractice; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; i