Android性能优化

1.布局优化

如果布局中既可以使用RelativeLayout,也可以使用LinearLayout,那么就采用LinearLayout,这是因为RelativeLayout的功能比较复杂,他的布局过程需要花费更多的CPU时间,FrameLayout和LinearLayout一样都是一种简单高效的ViewGroup,但是很多时候单纯的LinearLayout或者FramneLayout无法实现产品的效果,需要通过嵌套的方式来完成,这种情况下还是建议采用RelativeLayout,因为ViewGroup的嵌套相当于增加了布局的层级。

<include>标签、<merge>标签、ViewStub是布局优化的另一种手段。

注意,<include>标签只支持一android:layout_开通的属性,如果<iinclude>标指定了android:layout_*属性,那么要求android:layout_width和android:layout_heigth必须存在,否则其他android:layout_*属性无法生效。

<merge>标签一般和<include>标签一起使用从而减少布局的层级

eg

<LinearLayout xmls:android = "http://schemas.android.com/apk/res/android"

               android:orientation = "vertical"

               android:layout_width = "match_parent"

               android:layout_height = "match_parent"  

               >

               <include layout = "@layout/titlbar">

               <TextView  android :layout_width = "match_parent"

                         android:layout_height = "wrap_content"

                          >

</LinearLayout>

<merge xmls:android = "http://schemas.android.com/apk/res/android">

        <Button 

               android:layout_width = "wrap_content"

               android:layout_height = "wrap_content"  >

        <Button 

               android:layout_width = "wrap_content"

               android:layout_height = "wrap_content"  >

</merge>

本例中,由于当前布局是一个竖直方向的LinearLayout,这个时候如果被包含的布局文件也采用了竖直方向的LinearLayout,那么显然被包含的文件中的LinearLayout是多余的,通过<merge>标签就可以去掉多余的那一层LinearLayout

ViewStub

ViewStub的意义在于按需加载所需的布局而文件

<ViewStub

      android:id = "@+id/stup_import"

      android:inflated = "@+id/panel_import"

      android:layout = "@layout/layout_network_error"

      android:layout_width = "match_parent"

      android:layout_height = "match_parent" >

其中stub_import是ViewStub的Id,panel_import是@layout/layout_network_error这个布局元素的根布局元素的Id

在需要加载ViewStub中的布局时的方法

(ViewStub)findViewById(R.id.stub_import).setVisible(View.VISIBLE);

或者View inportPanel = ((ViewStub)findViewById(R.id.stub_import)).inflate();

ViewStub加载后,ViewStub就不再是整个布局结构中的一部分了,另外,目前ViewStub不支持<merge>标签


2.绘制优化

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

onDraw中不要创建新的局部对象,这是因为onDraw方法可能会被频繁调用,这样就会在一瞬间产生大量的临时对象,不仅用了过多的内存而且还会导致系统更加频繁gc,降低了程序的执行效率

onDrawf方法中不要做耗时的任务,也不能执行成千上万的循环操作,尽管每次都是轻量级的,但是大量的循环仍然抢占CPU的时间片,这会造成View的绘制过程不流畅

3.内存泄漏优化

a.静态变量导致的内存泄漏

eg

activity无法销毁

public class MainActivity extends Activity{

    private static final String TAG = "MainActivity";

    private static Context sContext;

    @override

    protected void onCreate(Bundle saveInstanceState){

        super.onCreate(saveInstanceState);.

        setContentView(R.layout.activity_main);

        sContext = this;

    }

}


public class MainActivity extends Activity{

    private static final String TAG = "MainActivity";

    private static View sView;

    @override

    protected void onCreate(Bundle saveInstanceState){

        super.onCreate(saveInstanceState);.

        setContentView(R.layout.activity_main);

        sView= newView(this) ;

    }

}

b.单例模式导致的内存泄漏

静态标量持有Activity,导致activity无法释放

c.属性动画导致的内存泄漏

属性动画有一类无限循环的动画,如果在Activity中播放此类动画且没有在onDestory中去停止动画,那么动画会一直播放下去,尽管已经无法在界面上看到播放效果,并且这个时候Activity的View会只有动画,而View有持有Activity,最终Activity无法释放,解决办法是在Activity的onDestory中调用animator.cancel()


4.响应速度优化

核心思想是避免在主线程中做耗时操作,可以将耗时操作放在线程中去执行,即采用异步的方式执行耗时操作,响应速度额过慢更多的体现在Activity的启动时出现黑屏现象。甚至出现ANR


5.ListView和Bitmap的优化

ListView的优化有:采用ViewHolder并避免在getView中执行耗时操作,根据列表滑动状态来控制任务的执行频率,比如当列表快速滑动时显然不适合开启大量的异步任务

bitmap优化:BitmapFactory.Options来根据需要对图片进行采样,主要用到BitmapFactory.Options的inSampleSize参数


6.线程优化

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


7优化的建议

避免创建过多的对象

不要过多的使用枚举,枚举占用的内存空间比整数大

常量要使用static final来修饰

使用Android的数据结构,比如Spar'seAr'ray和Pair等。他们都具有更好的性能

适当使用软引用和弱引用

采用内存缓存和磁盘缓存

尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄漏

你可能感兴趣的:(Android性能优化)