Android 代码优化

01.代码优化有哪些

  • 都是一些微优化,在性能方面看不出有什么显著的提升的。使用合适的算法和数据结构是优化程序性能的最主要手段。

02.lint检查去除无效代码

  • lint去除无效资源和代码
    • 如何检测哪些图片未被使用
      • 点击菜单栏 Analyze -> Run Inspection by Name -> unused resources -> Moudule ‘app’ -> OK,这样会搜出来哪些未被使用到未使用到xml和图片,如下:
    • 如何检测哪些无效代码
      • 使用Android Studio的Lint,步骤:点击菜单栏 Analyze -> Run Inspection by Name -> unused declaration -> Moudule ‘app’ -> OK

03.代码规范优化

  • 避免创建不必要的对象 不必要的对象应该避免创建:
    • 如果有需要拼接的字符串,那么可以优先考虑使用StringBuffer或者StringBuilder来进行拼接,而不是加号连接符,因为使用加号连接符会创建多余的对象,拼接的字符串越长,加号连接符的性能越低。
    • 当一个方法的返回值是String的时候,通常需要去判断一下这个String的作用是什么,如果明确知道调用方会将返回的String再进行拼接操作的话,可以考虑返回一个StringBuffer对象来代替,因为这样可以将一个对象的引用进行返回,而返回String的话就是创建了一个短生命周期的临时对象。
    • 尽可能地少创建临时对象,越少的对象意味着越少的GC操作。
    • nDraw方法里面不要执行对象的创建
  • 静态优于抽象
    • 如果你并不需要访问一个对系那个中的某些字段,只是想调用它的某些方法来去完成一项通用的功能,那么可以将这个方法设置成静态方法,调用速度提升15%-20%,同时也不用为了调用这个方法去专门创建对象了,也不用担心调用这个方法后是否会改变对象的状态(静态方法无法访问非静态字段)。
  • 对常量使用static final修饰符
    • static int intVal = 42; static String strVal = “Hello, world!”;
    • 编译器会为上面的代码生成一个初始方法,称为方法,该方法会在定义类第一次被使用的时候调用。这个方法会将42的值赋值到intVal当中,从字符串常量表中提取一个引用赋值到strVal上。当赋值完成后,我们就可以通过字段搜寻的方式去访问具体的值了。
    • final进行优化:
    • static final int intVal = 42; static final String strVal = “Hello, world!”;
    • 这样,定义类就不需要方法了,因为所有的常量都会在dex文件的初始化器当中进行初始化。当我们调用intVal时可以直接指向42的值,而调用strVal会用一种相对轻量级的字符串常量方式,而不是字段搜寻的方式。
    • 这种优化方式只对基本数据类型以及String类型的常量有效,对于其他数据类型的常量是无效的。
  • 在没有特殊原因的情况下,尽量使用基本数据类型来代替封装数据类型,int比Integer要更加有效,其它数据类型也是一样。
    • 基本数据类型的数组也要优于对象数据类型的数组。另外两个平行的数组要比一个封装好的对象数组更加高效,举个例子,Foo[]和Bar[]这样的数组,使用起来要比Custom(Foo,Bar)[]这样的一个数组高效的多。

04.View异常优化

  • view自定义控件异常销毁保存状态

    • 经常容易被人忽略,但是为了追求高质量代码,这个也有必要加上。举个例子!

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      @Override
      protected Parcelable onSaveInstanceState() {
      //异常情况保存重要信息。
      //return super.onSaveInstanceState();
      final Bundle bundle = new Bundle();
      bundle.putInt("selectedPosition",selectedPosition);
      bundle.putInt("flingSpeed",mFlingSpeed);
      bundle.putInt("orientation",orientation);
      return bundle;
      }

      @Override
      protected void onRestoreInstanceState(Parcelable state) {
      if (state instanceof Bundle) {
      final Bundle bundle = (Bundle) state;
      selectedPosition = bundle.getInt("selectedPosition",selectedPosition);
      mFlingSpeed = bundle.getInt("flingSpeed",mFlingSpeed);
      orientation = bundle.getInt("orientation",orientation);
      return;
      }
      super.onRestoreInstanceState(state);
      }

05.去除淡黄色警告优化

  • 淡黄色警告虽然不会造成崩溃,但是作为程序员还是要尽量去除淡黄色警告,规范代码

06.合理使用集合

  • 使用优化过的数据集合
    • Android提供了一系列优化过后的数据集合工具类,如SparseArray、SparseBooleanArray、LongSparseArray,使用这些API可以让我们的程序更加高效。HashMap工具类会相对比较低效,因为它需要为每一个键值对都提供一个对象入口,而SparseArray就避免掉了基本数据类型转换成对象数据类型的时间。

07.Activity不可见优化

  • 当Activity界面不可见时释放内存
    • 当用户打开了另外一个程序,我们的程序界面已经不可见的时候,我们应当将所有和界面相关的资源进行释放。重写Activity的onTrimMemory()方法,然后在这个方法中监听TRIM_MEMORY_UI_HIDDEN这个级别,一旦触发说明用户离开了程序,此时就可以进行资源释放操作了。
  • 当时看到这个觉得很新奇的,但是具体还是没有用到,要是那个大神有具体操作方案,可以分享一下。

08.节制的使用Service

  • 节制的使用Service
    • 如果应用程序需要使用Service来执行后台任务的话,只有当任务正在执行的时候才应该让Service运行起来。当启动一个Service时,系统会倾向于将这个Service所依赖的进程进行保留,系统可以在LRUcache当中缓存的进程数量也会减少,导致切换程序的时候耗费更多性能。我们可以使用IntentService,当后台任务执行结束后会自动停止,避免了Service的内存泄漏。