Android 性能优化方法

Android 性能优化方法

开发中常会做一些性能优化,主要优化内容包括布局层级优化,绘制优化,内存泄露优化(音频,视频,io等回收),响应速度优化,ListView优化,Bitmap优化,线程优化以及一些性能优化,在面试中面试官也会经常问到该点 . 前面博文我收集的各大厂等面试题

文章目录

  • Android 性能优化方法
    • 布局优化
    • 绘制优化
    • 内存泄露优化
    • 响应速度优化
    • ListView和Bitmap优化
    • 线程优化
    • 心灵激励
    • 尾言

布局优化

布局优化思想,尽量减少布局文件的层级,层级少,意味Android绘制时的工作量少了,程序的性能自然提高了.

  1. 删除布局中无用的控件和层级
  2. 有选择使用性能较低的ViewGroup,如:RelativeLayout
  3. 优先使用LinearLayout,相对RelativeLayout,其功能比较简单,花费较少的CPU时间
  4. 需要复杂嵌套实现效果时,这种情况下建议采用RelativeLayout
  5. 采用标签在于布局重用,标签降低减少布局层级和ViewStub按需加载



    

    

        
        

            

            

        

        

        
        

            

            

        

        
        

            

            

        

        

        
        

            

            

        

        
        

            

            

        

    

    

绘制优化

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

  1. onDraw中不要创建新的局部对象,因为onDraw方法可能会被频繁调用,这样就会在一瞬间产生大量的临时对象,这不仅占用了过多的内存而且还会导致系统更加频繁gc,降低了程序的执行效率
  2. onDraw方法中不要做耗时的任务,也不能执行复杂的循环操作,尽管每次循环都很轻量级,但是大量的循环任然十分抢占CPU的时间片,这回造成View的绘制过程不流畅.
  3. Google官方给出的性能优化典范中的标准,View的绘制帧率保证60fps是最佳的,这就要求每帧的绘制时间不超过16ms(16 = 1000/60),虽然程序很难保证16ms这个时间,但是尽量降低onDraw方法的复杂度总是切实有效的.

内存泄露优化

内存泄露在开发过程中是一个需要重视的问题,但是由于内存泄露问题 对开发人员的经验和开发意识有较高的要求,因此这也是开发人员最容易犯的错误之一.内存泄露的优化分为两个方面,一方面是开发过程中避免写出有内存泄露的代码.另一方面是通过一些分析工具找出潜在的内存泄露

  1. 静态变量导致的内存泄露,(在dalvik虚拟机中,static变量所指向的内存引用,如果不把它设置为null,GC是永远不会回收这个对象的),处理: 对象=null;
  2. 单例模式导致的内存泄露,如下

单例模式导致的内存泄露:Activty是间接继承于Context的,当这Activity退出时,Activity应该被回收, 但是单例中又持有它的引用,导致Activity回收失败,造成内存泄漏。

package com.kx.singleinstance;

import android.content.Context;

/**
 * @ 创建:   kx
 * @ 时间:    2018/11/13
 * @ 描述:
 */

public class AppManager  {

    private static AppManager instance;
    
    private  Context mContext;

    public AppManager(Context context) {
        mContext = context;
    }

    public  static AppManager getInstance(Context context){
        if(instance == null){
            instance = new AppManager(context);
        }
        return  instance;
    }
}

单例模式导致的内存泄露改进:使用Applicaton的Context,而我们单例的生命周期和应用的一样长,这样就防止了内存泄漏。

package com.kx.singleinstance;

import android.content.Context;

/**
 * @ 创建:   kx
 * @ 时间:    2018/11/13
 * @ 描述:
 */

public class AppManager  {


    private static AppManager instance;
    
    private  Context mContext;

    public AppManager(Context context) {
        //使用Applicaton的Context,而我们单例的生命周期和应用的一样长,这样就防止了内存泄漏。
        mContext = context.getApplicationContext();
    }

    public  static AppManager getInstance(Context context){
        if(instance == null){
            instance = new AppManager(context);
        }
        return  instance;
    }
}

  1. 属性动画导致的内存泄露,属性动画无限循环动画,Activity与View相互持有,导致Activity无法释放. 解决: onDestroy 对动画 animator.cancel()来停止动画

响应速度优化

响应速度优化的核心思想是避免在主线程中做耗时操作,这里具体可参考前面的文章.耗时操作放在线程中去执行,即采用异步的方式执行耗时操作.响应速度过慢更多地体现在Activity的启动速度上面,如果在主线中做太多事情,会导致Activity启动时出现黑屏现象,甚至出现ANR, Android规定,Activity如果5秒钟之内无法响应屏幕触摸事件或者键盘输入时间就会出现ANR,而BroadcastReceiver如果10秒钟之内还未执行完操作也会出现ANR.

ListView和Bitmap优化

listview优化

  1. convertView的使用,主要优化加载布局问题

  2. 内部类ViewHolder的使用,采用ViewHolder并避免在getView中执行耗时操作

  3. 滑动的时候不载入图片

    在ListView滑动的时候载入图片,那样会使ListView变得卡顿,所以我们须要再监听器里面监听ListView的状态。假设滑动的时候,停止载入图片,假设没有滑动,则開始载入图片

listView.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView listView, int scrollState) {
                    //停止载入图片 
                    if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
                            imageLoader.stopProcessingQueue();
                    } else {
                    //開始载入图片
                            imageLoader.startProcessingQueue();
                    }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    // TODO Auto-generated method stub

            }
    });
  1. 将ListView的scrollingCache和animateCache设置为false

    A.scrollingCache: scrollingCache本质上是drawing cache,你能够让一个View将他自己的drawing保存在cache中(保存为一个bitmap),这样下次再显示View的时候就不用重画了,而是从cache中取出。默认情况下drawing cahce是禁用的。由于它太耗内存了,可是它确实比重画来的更加平滑。而在ListView中,scrollingCache是默认开启的,我们能够手动将它关闭。

    B.animateCache: ListView默认开启了animateCache,这会消耗大量的内存,因此会频繁调用GC,我们能够手动将它关闭掉


  1. 降低item的布局的深度

    尽量降低item布局深度,由于当滑动ListView的时候,这回直接导致測量与绘制,因此会浪费大量的时间。所以我们应该将一些不必要的布局嵌套关系去掉。

  2. 分批加载与分页加载相结合

线程优化

线程优化的核心思想是采用线程池,避免程序中存在大量的Thread.线程池可以重用内部的线程,从而避免了线程的创建和销毁所带来的性能开销,同时线程池还能有效地控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象的发生.因此在实际开发中,我们要尽量采用线程池,而不是每次都要创建一个Thread对象

心灵激励

激励:为自己技术增值,量变引起质变.博主依稀记得当前的语文老师说的一句话:“态度决定高度”,博主想对所有的读者说"过去的已经过去,你的未来由你现在把握".

尾言

本文如有错误或不当之处,欢迎读者留言斧正,互相交流学习,博主不胜感激.联系邮箱[email protected]

你可能感兴趣的:(Android)