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中配置相应的图片资源,否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。


代码如下:

InputStreamis=this.getResources().openRawResource(R.drawable.pic1);
BitmapFactory.Optionsoptions=newBitmapFactory.Options();
options.inJustDecodeBounds=false;
options.inSampleSize=10;//width,hight设为原来的十分一
Bitmapbtp=BitmapFactory.decodeStream(is,null,options);

代码如下:

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

代码如下:

/**
*以最省内存的方式读取本地资源的图片
*@paramcontext
*@paramresId
*@return
*/
publicstaticBitmapreadBitMap(Contextcontext,intresId){
BitmapFactory.Optionsopt=newBitmapFactory.Options();
opt.inPreferredConfig=Bitmap.Config.RGB_565;
opt.inPurgeable=true;
opt.inInputShareable=true;
//获取资源图片
InputStreamis=context.getResources().openRawResource(resId);
returnBitmapFactory.decodeStream(is,null,opt);
}

option中的值指的是,图片进行缩放的比例,SDK中建议其值是2的指数值,值越大会导致图片不清晰。长度、宽度都只有原图片的1/2。图片大小减少,占用的内存自然也变小了。这么做的弊端是图片质量变差,inSampleSize的值越大,图片的质量就越差。由于各手机厂商缩放图片的算法不同,在不同手机上的缩放图片质量可能会不同。笔者就遭遇过moto手机上图片缩放后质量可以接受,三星手机上同样的缩放比例,质量却差很多的情况。

Android中有四种,分别是
ALPHA_8:每个像素占用1byte内存
ARGB_4444:每个像素占用2byte内存
ARGB_8888:每个像素占用4byte内存
RGB_565:每个像素占用2byte内存
Android默认的颜色模式为ARGB_8888,这个颜色模式色彩最细腻,显示质量最高。但同样的,占用的内存也最大。
以上代码即是将1.png以ARGB_4444模式读出。内存减少虽然不如第一种方法明显,但是对于大多数图片,看不出与ARGB_8888模式有什么差别。不过在读取有渐变效果的图片时,可能有颜色条出现。另外,会影响图片的特效处理。
优化Dalvik虚拟机的堆内存分配。对于Android平台来说,其托管层使用的DalvikJavaVM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。使用方法:


代码如下:

privatefinalstaticfloatTARGET_HEAP_UTILIZATION=0.75f;
VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);

即可。
还有就是可以定义堆内存的大小。


代码如下:

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

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

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


代码如下:

Matrixmatrix=newMatrix();
floatnewWidth=200;//图片放大后的宽度
floatnewHeight=300;//图片放大后的长度
matrix.postScale(newWidth/img.getWidth(),newHeight/img.getHeight());
Bitmapimg1=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,所以实际内存还是减少了。

(0)

相关推荐

  • Android悬浮窗屏蔽悬浮窗外部所有的点击事件的实例代码

    Android可以在所有应用上方添加View,就是给WindowManager添加一个View,在创建的View的时候可以给这个View设置LayoutParams(android.view.WindowManager.LayoutParams.LayoutParams())属性,默认是屏蔽View区域以外的所有点击事件,即在显示View的时候,屏幕的其它区域都不可点击,包括菜单和返回键等. 当给LayoutParams设置合适的flag后,其它区域就可以响应点击了. 示例代码: /** * 创

  • Android中悬浮窗口的实现原理实例分析

    本文实例讲述了Android中悬浮窗口的实现原理.分享给大家供大家参考.具体如下: 用了我一个周末的时间,个中愤懑就不说了,就这个问题,我翻遍全球网络没有一篇像样的资料,现在将实现原理简单叙述如下: 调用WindowManager,并设置WindowManager.LayoutParams的相关属性,通过WindowManager的addView方法创建View,这样产生出来的View根据WindowManager.LayoutParams属性不同,效果也就不同了.比如创建系统顶级窗口,实现悬浮

  • android 添加随意拖动的桌面悬浮窗口

    用过新版本android 360手机助手都人都对 360中只在桌面显示一个小小悬浮窗口羡慕不已吧? 其实实现这种功能,主要有两步: 1.判断当前显示的是为桌面.这个内容我在前面的帖子里面已经有过介绍,如果还没看过的赶快稳步看一下哦. 2.使用windowManager往最顶层添加一个View .这个知识点就是为本文主要讲解的内容哦.在本文的讲解中,我们还会讲到下面的知识点: a.如果获取到状态栏的高度 b.悬浮窗口的拖动 c.悬浮窗口的点击事件 有开始之前,我们先来看一下效果图:  接下来我们来

  • Android实现类似360,QQ管家那样的悬浮窗

    一.前言: 我手机从来不装这些东西,不过,有次看到同事的android手机上,有个QQ管家在桌面上浮着,同事拖动管家时,管家就变成一只鸟,桌面下方还有个弹弓,桌面顶部有只乌鸦,把管家也就是鸟拖动到弹弓那,然后,松手,鸟就飞出去.这个过程是动画过程,做的事,实际上是清楚内存. 二:原理: 其实,没什么原理,用到的就是WindowManager以及WindowManager.LayoutParams,对这个LayoutParams做文章,当设置为属性后,然后,创建一个View,将这个View添加到W

  • android编程实现悬浮窗体的方法

    本文实例讲述了android编程实现悬浮窗体的方法.分享给大家供大家参考,具体如下: 突然对悬浮窗体感兴趣,查资料做了个小Demo,效果是点击按钮后,关闭当前Activity,显示悬浮窗口,窗口可以拖动,双击后消失.效果图如下: 它的使用原理很简单,就是借用了WindowManager这个管理类来实现的. 1.首先在AndroidManifest.xml中添加使用权限: 复制代码 代码如下: <uses-permission android:name="android.permission

  • 不依赖于Activity的Android全局悬浮窗的实现

    前言 当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可跳转到安全卫士的操作界面,而且该浮动窗口不受其他activity的覆盖影响仍然可见(多米音乐也有相关的和主界面交互的悬浮小窗口).那么这种不受Activity界面影响的悬浮窗口是怎么实现的呢? Android悬浮窗实现 实现基础 Android悬浮窗实现使用WindowManager WindowManager介绍 通过Context.getSystemService(Context.WINDOW_S

  • Android系统检测程序内存占用各种方法

    1.检查系统总内存 复制代码 代码如下: liuhx@uc ~ $ adb shell cat /proc/meminfo MemTotal:         840868 kB MemFree:          457344 kB Buffers:            1744 kB Cached:           203064 kB SwapCached:            0 kB Active:           234932 kB Inactive:         12

  • 详解android6.0版本下悬浮窗实现

    悬浮窗在安卓中实现起来还是比较容易的,这几天在网上温习了相关资料,运行在我安卓6.0手机上才发现,原来在6.0手机上不是行的. 第一反应肯定是权限相关问题,做了相关处理后,果然让悬浮窗原形毕露了.直接贴代码. public class MainActivity extends AppCompatActivity { private static final int ALERT_WINDOW_PERMISSION_CODE = 100; private Button start_float; @O

  • Android实现带磁性的悬浮窗体效果

    本文实例讲述了Android实现带磁性的悬浮窗体效果.分享给大家供大家参考,具体如下: 带磁性的悬浮窗体,类似于360绿色小人 主要实现的是: 1.悬浮所有窗体之上 2.有吸引力,吸附于屏幕边上 3.有点击效果 下面我就实现上面三点,简单封装了个FloatView 先看下本次Demo的效果图,然后再看代码, 效果图: FloatView代码如下 package com.manymore13.flowwindowdemo; import android.content.Context; impor

  • Android编程实现悬浮窗获取并显示当前内存使用量的方法

    本文实例讲述了Android编程实现悬浮窗获取并显示当前内存使用量的方法.分享给大家供大家参考,具体如下: 运行效果: 其中: 这一块就是悬浮窗,可以随意拖动,动态显示当前内存使用量. 下面看一下代码是如何实现的: 悬浮窗的实现是用了一个service,为什么要用service呢?了解service特点的大体就会明白.下面看一下: public class FloatService extends Service { WindowManager wm = null; WindowManager.

  • Android实现桌面悬浮窗、蒙板效果实例代码

    现在很多安全类的软件,比如360手机助手,百度手机助手等等,都有一个悬浮窗,可以飘浮在桌面上,方便用户使用一些常用的操作. 今天这篇文章,就是介绍如何实现桌面悬浮窗效果的. 首先,看一下效果图. 悬浮窗一共分为两个部分,一个是平常显示的小窗口,另外一个是点击小窗口显示出来的二级悬浮窗口. 首先,先看一下这个项目的目录结构. 最关键的就是红框内的四个类. 首先,FloatWindowService是一个后台的服务类,主要负责在后台不断的刷新桌面上的小悬浮窗口,否则会导致更换界面之后,悬浮窗口也会随

  • Android手机悬浮窗口小案例

    本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下 –主页面--– //布局中就一个Button public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

随机推荐