Android性能优化

来源:互联网 发布:清理arp 命令 centos 编辑:程序博客网 时间:2024/06/08 15:42

最近在看《开发艺术探索》,写的很棒的一本书,大家有时间可以看看,今天再次看了一下 Android性能优化。

Android的内存和CPU的使用都受到了限制,不能像PC机那样使用内存和CPU ,过多的使用内存会造成OOM(内存溢出);过多的使用CPU资源,即执行大型的耗时任务,会造成程序卡顿,甚至会发生ANR(程序无响应),因此,Android的性能问题在编程时很重要。下面介绍一些Android性能优化的方法,有一些我也理解的不透彻。

一.布局优化

我们知道android的界面很多都是布局层级的嵌套,即View树,在写XML文件时,要做到布局优化,就要尽量减少布局层级,这样View在绘制过程中的工作量就会减少。

首先避免写布局中的无用控件和层级,再者,选择相对效率高的布局,比如,可以用RelativeLayout 也可以用 LinearLayout ,在层级相同的情况下,选择LinearLayout ,因为RelativeLayout 的布局过程较复杂。

布局的优化还有以下三种:

(1)使用<include>标签

作用:将指定的布局文件加载到当前布局文件,举个例子:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">        <include layout="@layout/titlebar"/>    </LinearLayout>

如果还要制定其他的属性 , include只支持layout_开头的属性,还有 id,如下面所示

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">        <include         android:id="@+id/new_title"        android:layout_width="match_parent"        android:layout_height="match_parent"        layout="@layout/titlebar"/>    </LinearLayout>
其他的属性,比如background 这些,在titlebar.xml文件中实现即可。

(2)使用<merge>标签

<merge>标签一般和<include>一起使用,见很少布局的层级,比如,当前布局是一个水平方向的LinearLayout ,其内部也包含一个竖直方向的LinearLayout ,那么就可以通过<merge>标签去掉多余的内部布局文件。

(3)ViewStub

作用:在需要的时候加载所需的布局文件,本身不参与任何的布局和绘制过程

注意:不支持<merge>标签

ViewStub是继承自View,

它的使用场景,比如网络异常时的界面,这个没有必要再整个界面初始化的时候将其加载进来,即可用ViewStub。

如下所示,android:id是ViewStub的id,而android:inflatedId是布局的根元素的id。

<ViewStub android:id="@+id/xxx"  android:inflatedId="@+id/yyy"  android:layout="@layout/zzz"  ...</ViewStub>
需要加载ViewStub中的布局的时候,可以按照如下两种方式进行:

((ViewStub)findViewById(R.id.xx)).setVisibility(View.VISIBLE);
或者

View importPanel = ((ViewStub)findViewById(R.id.stub_import)).inflate();

二,绘制优化


绘制优化是指View的onDraw方法要避免执行大量的操作:

  • 在onDraw中不要创建新的局部对象,这是因为onDraw方法可能会被频繁调用,这样就会在一瞬间产生大量的临时对象,这不仅占用了过多的内存而且还会导致系统更加频繁的gc,降低了程序的执行效率。
  • onDraw方法中不要指定耗时任务,也不能执行成千上万次的循环操作,View的绘制帧率保证60fps是最佳的,这就要求每帧的绘制时间不超过16ms,虽然程序很难保证16ms这个时间,但是尽量降低onDraw方法的复杂度总是切实有效的。
三,内存泄漏优化

(1)静态变量导致

(2)单例模式导致  因为单例模式的生命周期和Application保持一致。

(3)属性动画   比如动画一直在播放

四,响应速度优化和ANR日志分析

  1. ANR出现的情况:Activity如果5秒内没有响应屏幕触摸事件或者键盘输入事件就会ANR。而BroadcastReceiver如果10s没有执行完操作也会出现ANR。
  2. 当一个进程发生了ANR之后,系统会在/data/anr目录下创建一个文件traces.txt,通过分析这个文件就能定位ANR的原因。
五,ListView和Bitmap优化

  1. ListView优化:采用ViewHolder并避免在getView方法中执行耗时操作;根据列表的滑动状态来绘制任务的执行效率;可以尝试开启硬件加速期来使ListView的滑动更加流畅。
  2. Bitmap优化:根据需要对图片进行采样,主要是通过BitmapFactory.Options来根据需要对图片进行采样,采样主要用到了BitmapFactory.Options的inSampleSize参数。
六,线程优化

采用线程池,避免程序中存在大量的Thread。线程池可以重用内部的线程,从而避免了线程的创建和销毁所带来的性能开销,同时线程池还能有效的控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象的发生。

关于性能优化的一些注意点:

  • 避免 创建过多的对象
  • 不要过多的使用枚举,枚举占用的内存空间要比整形大
  • 常量请用static final来修饰
  • 使用一些Android特有的数据结构,比如SparseArray和Pair等,它们都具有更好的性能
  • 适当使用软引用和弱引用
  • 采用内存缓存和磁盘缓存
  • 尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄漏
对于内存泄漏那块,是有分析工具MAT,可以试着测试一下自己的项目,看一下有没有内存泄漏。

如有不足之处,请多多指教。




1 0
原创粉丝点击