热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android开发分享Android中对于图片的内存优化方法

1.对图片本身进行操作尽量不要使用setimagebitmap、setimageresource、bitmapfactory.decoder

1. 对图片本身进行操作

上述就是android开发分享Android 中对于图片的内存优化方法的全部内容,如果对大家有所用处且需要了解更多关于Android学习教程,希望大家多多关注—编程笔记

尽量不要使用 setimagebitmap、setimageresource、 bitmapfactory.decoderesource 来设置一张大图,因为这些方法在完成 decode 后,最终都是通过 java 层的 createbitmap 来完成的,需要消耗更多内存。因此,改用先通过 bitmapfactory.decodestream 方法,创建出一个 bitmap,再将其设为 imageview 的 source,decodestream 最大的秘密在于其直接调用 jni>>nativedecodeasset() 来完成 decode,无需再使用 java 层的 createbitmap,从而节省了 java 层的空间。如果在读取时加上图片的 config 参数,可以更有效的减少加载的内存,从而更有效阻止抛出内存异常。另外,decodestream 直接拿图片来读取字节码了,不会根据机器的各种分辨率来自动适应,使用了 decodestream 之后,需要在 hdpi 和 mdpi,ldpi 中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。

代码如下:
inputstream is = this.getresources().openrawresource(r.drawable.pic);
bitmapfactory.options optiOns= new bitmapfactory.options();
options.injustdecodebounds = false;
options.insamplesize = 2;
bitmap btp =bitmapfactory.decodestream(is,null,options);

以上代码即是读取 drawable 下名为 pic 图片的缩略图,长度、宽度都只有原图片的 1/2。图片大小减少,占用的内存自然也变小了。这么做的弊端是图片质量变差,insamplesize 的值越大,图片的质量就越差。由于各手机厂商缩放图片的算法不同,在不同手机上的缩放图片质量可能会不同。

2. 调用图片的 recycle() 方法

代码如下:
if(!bmp.isrecycle() ){
   bmp.recycle()    //回收图片所占的内存
   system.gc()      //提醒系统及时回收
}

这种方法其实不是真正降低图片内存的方法。主要目的是标记图片对象,方便回收图片对象的本地数据。图片对象的本地数据占用的内存最大,而且与程序 java 部分的内存是分开计算的。所以经常出现 java heap 足够使用,而图片发生 outofmemoryerror 的情况。在图片不使用时调用该方法,可以有效降低图片本地数据的峰值,从而减少 outofmemoryerror 的概率。不过调用了 recycle() 的图片对象处于“废弃”状态,调用时会造成程序错误。所以在无法保证该图片对象绝对不会被再次调用的情况下,不建议使用该方法。特别要注意已经用 setimagebitmap(bitmap
img) 方法分配给控件的图片对象,可能会被系统类库调用,造成程序错误。

 

3. 以最省内存的方式读取本地资源的图片

代码如下:
/**
 * 以最省内存的方式读取本地资源的图片
 */
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); 
}

android 中加载图片的颜色模式有四种,分别是:alpha_8:每个像素占用 1byte 内存、argb_4444:每个像素占用 2byte 内存、argb_8888:每个像素占用 4byte 内存、rgb_565:每个像素占用 2byte 内存。android默认的颜色模式为argb_8888,这个颜色模式色彩最细腻,显示质量最高。但同样的,占用的内存也最大。以上代码即是将图片资源以 rgb_565 (或以 argb_4444)模式读出。内存减少虽然不如第一种方法明显,但是对于大多数图片,看不出与 argb_8888 模式有什么差别。不过在读取有渐变效果的图片时,可能有颜色条出现。另外,会影响图片的特效处理。

 

4. 使用 matrix 对象放大的图片如何更改颜色模式:

虽然使用 matrix 对象放大图片,必定会耗费更多的内存,但有时候也不得不这样做。放大后的图片使用的 argb_8888 颜色模式,就算原图片是argb_4444 颜色模式也一样,而且没有办法在放大时直接指定颜色模式。可以采用以下办法更改图片颜色模式。

代码如下:
matrix matrix = new matrix();
float newwidth = 200;       // 图片放大后的宽度
float newheight = 300;      // 图片放大后的长度
matrix.postscale(newwidth / img.getwidth(), newheight/ img.getheight());
bitmap img1 = bitmap.createbitmap(img, 0, 0, img.getwidth(), img.getheight(), matrix, true);// 得到放大图片
img2 = img1.copy(bitmap.config.argb_4444, false);                           // 得到 argb_4444 颜色模式的图片
img = null;
img1 = null;

这里比起本来的图片额外生成了一个图片对象 img1。然则体系会主动收受接管 img1,所以实际内存还是削减了。

归结起来还是以缩略图模式读取图片和削减图片中每个像素占用的内存最为有效。 这两种办法固然有效,然则也有各自的弊病。实际开辟中还是应当按照景象酌情应用。最王道的办法,还是避免垃圾对象的产生。例如在 listview 的应用中,复用 convertview 等。若是应用 asynctask 加载图片,要及时将引用的 imageview 对象置为 null。因为 asynctask 是用线程池实现的,所以此中引用的对象可能会拥有很长的生命周期,造成 gc 无法开释。我还是信赖 android 的内存收受接管机制的,recycle 什么的固然必然程度上有效,但总感觉不合适 java 内存收受接管的原则。


推荐阅读
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 近来有一个需求,是需要在androidjava基础库中插入一些log信息,完成这个工作需要的前置条件有编译好的android源码具体android源码如何编译,这 ... [详细]
author-avatar
米年爱秋天
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有