专栏首页非著名程序员有效解决Android加载大图片内存溢出的问题

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

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

非著名程序员

今天在交流群里,有人问我他经常遇到加载图片时内存溢出的问题,遇到的情况还是在自己的测试机或者手机里没有问题,做好了, 到了客户手机里就内存溢出了。其实有时候不同的手机和不同的系统对内存的要求不一样,尤其是图片,所以可能会遇到这样的问题。那我们怎么样有效解决Android加载大图片时内存溢出的问题? 那么接下来,我们就来说说这个问题: 首先,我们要知道尽量的不要使用setImageResource或setImageBitmap或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中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小,显示出来的大小就不对了,不适配。 现在给大家比较好用的方法,如下:

/**
    * 以最省内存的方式读取本地资源的图片
    *  
    * @param context
    * @param resId
    * @return
    */  
   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);  
   }  

其实通过下面的两种方式也可以:

1. InputStream is = this.getResources().openRawResource(R.drawable.pic1);
    BitmapFactory.Options options=new BitmapFactory.Options();
    options.inJustDecodeBounds = false;
    options.inSampleSize = 5;   //width,hight设为原来的五分之一
    Bitmap btp =BitmapFactory.decodeStream(is,null,options);
2. if(!bmp.isRecycle() ){
        bmp.recycle()   //回收图片所占的内存
        system.gc()  //提醒系统及时回收
}

我也稍微再说一下图片占用进程的内存算法吧: android中处理图片的基础类是Bitmap,顾名思义,就是位图。占用内存的算法如下:图片的width*height*Config。如果Config设置为ARGB_8888,那么上面的Config就是4。一张480*320的图片占用的内存就是480*320*4 byte。其实是在默认情况下android进程的内存占用量为16M,因为Bitmap他除了java中持有数据外,底层C++的skia图形库还会持有一个SKBitmap对象,因此一般图片占用内存推荐大小应该不超过8M。这个大小是可以调整,但是只有在编译源代码时可以设置这个大小的参数。

本文分享自微信公众号 - 非著名程序员(non-famous-coder)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-07-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android 开发如何做好内存优化

    Android的一个应用程序的内存泄露对别的应用程序影响不大。为了能够使得Android应用程序安全且快速的运行,Android的每个应用程序都会使用一个专有...

    非著名程序员
  • Android进阶:Android内存管理之道

    对于移动应用开发,不管是Android还是IOS,内存都是永远的痛。但是合理的编写代码,会避免OOM的出现。 相信一步步走过来的Android从业者,每个人都...

    非著名程序员
  • Android内存泄漏终极解决篇(上)

    一、概述 Android内存的文章详见:http://blog.csdn.net/linghu_java/article/details/39480761 在...

    非著名程序员
  • 吊打Java面试官-Java内存模型深入详解(JMM)

    为了提高程序运行的性能,现代CPU在很多方面对程序进行了优化。: 例如: CPU高速缓存。 尽可能地避免处理器访问主内存的时间开销,处理器大多会利用缓 存...

    JavaEdge
  • Android 内存优化总结&实践

    导语 智能手机发展到今天已经有十几个年头,手机的软硬件都已经发生了翻天覆地的变化,特别是Android阵营,从一开始的一两百M到今天动辄4G,6G内存。然而大部...

    腾讯Bugly
  • 探索 Java 内存管理机制,面试别被问住了

    整理的目的是让我自己能对 Java 内存管理相关的知识的认识更全面一些,分享的目的是希望大家也能从这些知识中得到一些启发。

    Android扫地僧
  • Node.js中的内存泄漏分析

    内存泄漏(Memory Leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。如果内存泄漏的位置比较关键,那么随着处理的进行可能持有越来越多的无用...

    FB客服
  • 解Bug之路-记一次JVM堆外内存泄露Bug的查找

    用户1263954
  • 今咱们来聊聊JVM 堆外内存泄露的BUG是如何查找的

    JVM的堆外内存泄露的定位一直是个比较棘手的问题。此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤了Bug的源头。笔...

    美的让人心动
  • iOS---内存分析

    用户1941540

扫码关注云+社区

领取腾讯云代金券