Android之——图片的内存优化

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46972817

1. 对图片本身进行操作

尽量不要使用 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 内存收受接管的原则。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 16:53:25

Android之——图片的内存优化的相关文章

Android 中对于图片的内存优化方法

Android 中对于图片的内存优化方法,需要的朋友可以参考一下 1. 对图片本身进行操作 尽量不要使用 setImageBitmap.setImageResource. BitmapFactory.decodeResource 来设置一张大图,因为这些方法在完成 decode 后,最终都是通过 Java 层的 createBitmap 来完成的,需要消耗更多内存.因此,改用先通过 BitmapFactory.decodeStream 方法,创建出一个 bitmap,再将其设为 ImageVie

Android之——性能与内存优化

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46987951 写出高效代码的两条基本的原则:(1)不要做不必要的事:(2)不要分配不必要的内存. 1. 内存优化      Android系统对每个软件所能使用的RAM空间进行了限制(如:Nexus one 对每个软件的内存限制是24M),同时Java语言本身比较消耗内存,dalvik虚拟机也要占用一定的内存空间,所以合理使用内存,彰显出一个程序员的素质和技能. 1) 了解JIT

android 开发如何做内存优化

网上看的一篇很好的文章;http://www.gforetell.com/?/question/id-111__uid-focus 不少人认为JAVA程序,因为有垃圾回收机制,应该没有内存泄露.其实如果我们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然该对象占用的内存就无法被使用,这就造成了内存泄露.如果我们的java运行很久,而这种内存泄露不断的发生,最后就没内存可用了.当然java的,内存泄漏和C/C++是不一样的.如果java程序完全结束后,它所有

Android大图加载内存优化(如何防止OutOfMemory)

一.简介 移动设备不断发展的今天,有的人认为内存已经足够大了,不用再管什么内存优化,Java是虚拟机可以帮我维护内存.其实内存空间资源还是很宝贵的,不管手机内存有多大,系统分配给单个应用的内存空间还是很有限的大致有16M,64M,128M等.在Android中加载大图会非常消耗系统资源,16M的图片大致可以存储3张1024X1536质量为ARGB_8888的图片,这里边还不包含其它Object所占的资源.软件在系统上运行,环境是很复杂的,可能测试的时候有限的测试次数上没有发现内存泄漏问题,但是在

使用Picasso加载图片的内存优化实践

0 说明 现在Android开源库中有许多图片加载框架,本文以picasso为例,总结下开发过程中的一些优化经验,使用的picasso版本如下 compile 'com.squareup.picasso:picasso:2.5.2' 1 图片裁剪 在列表页尽量使用裁剪后的图片,在查看大图模式下才加载完整的图片. 图片裁剪示例 Picasso.with( imageView.getContext() ) .load(url) .resize(dp2px(250),dp2px(250)) .cent

Android APP内存优化之图片优化

网上有很多大拿分享的关于Android性能优化的文章,主要是通过各种工具分析,使用合理的技巧优化APP的体验,提升APP的流畅度,但关于内存优化的文章很少有看到.在Android设备内存动不动就上G的情况下,的确没有必要去太在意APP对Android系统内存的消耗,但在实际工作中我做的是教育类的小学APP,APP中的按钮.背景.动画变换基本上全是图片,在2K屏上(分辨率2048*1536)一张背景图片就会占用内存12M,来回切换几次内存占用就会增涨到上百兆,为了在不影响APP的视觉效果的前提下,

Android学习之内存优化(一)—— 图片处理

在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. Bitmap类的构造方法都是私有的,所以开发者不能直接new出一个Bitmap对象,只能通过BitmapFactory类的各种静态方法来实例化一个Bitmap. 对于图片,内存优化中有两个手段,一是减少图片本身所占的内存.二是缓存经常使用的图

Android内存优化1-对Bitmap的内存优化

在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. 1) 要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Android系统有自己的垃圾回收机制,可以不定期的回收掉不使用的内存空间,当然也包括Bitmap的空间.那为什么还需

【转】Android开发之Bitmap的内存优化详解

本文来源:转载自: http://mobile.51cto.com/abased-410796.htm 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. 1.要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Android系