Android -性能优化

224 阅读4分钟
布局优化
  1. 如果父控件有颜色,也是自己需要的颜色,那么就不必在子控件加背景颜色
  2. 如果每个自控件的颜色不太一样,而且可以完全覆盖父控件,那么就不需要再父控件上加背景颜色
  3. 尽量减少不必要的嵌套
  4. 能用 LinearLayout 和 FrameLayout,就不要用 RelativeLayout,因为 RelativeLayout 控件相对比较复杂,测绘也想要耗时。
  5. 使用 include 和 merge 增加复用,减少层级
  6. ViewStub 按需加载,更加轻便
  7. 复杂界面可选择 ConstraintLayout,可有效减少层级
绘制优化
  1. onDraw 中不要创建新的局部对象
  2. onDraw 方法中不要做耗时的任务
内存优化
  1. 集合类泄漏
  2. 单例/静态变量造成的内存泄漏
  3. 匿名内部类/非静态内部类
  4. 资源未关闭造成的内存泄漏
    • 网络、文件等流忘记关闭
    • 手动注册广播时,退出时忘记 unregisterReceiver()
    • Service 执行完后忘记 stopSelf()
    • EventBus 等观察者模式的框架忘记手动解除注册
启动速度优化
  1. 利用提前展示出来的 Window,快速展示出来一个界面
  2. 避免在启动时做密集沉重的初始化
  3. 避免 I/O 操作、反序列化、网络操作、布局嵌套等
包体积优化
  1. 我们可以开启资源压缩,自动删除无用的资源
  2. 重用资源
  3. 能自己用 XML 写 Drawable
  4. 压缩 PNG 和 JPEG 文件
  5. 使用 WebP 文件格式
  6. 使用矢量图形
  7. 代码混淆
  8. 插件化
耗电优化
  1. 使用 JobScheduler 调度任务

  2. 使用懒惰法则

    减少 你的应用程序可以删除冗余操作吗?例如,它是否可以缓存下载的数据而不是重复唤醒无线电以重新下载数据?

    推迟 应用是否需要立即执行操作?例如,它可以等到设备充电才能将数据备份到云端吗?

    合并 可以批处理工作,而不是多次将设备置于活动状态吗?例如,几十个应用程序是否真的有必要在不同时间打开收音机发送邮件?在一次唤醒收音机期间,是否可以传输消息?

ListView 和 Bitmap 优化

针对 ListView 优化,主要是合理使用 ViewHolder。创建一个内部类 ViewHolder,里面的成员变量和 view 中所包含的组件个数、类型相同,在 convertview 为 null的时候,把 findviewbyId 找到的控件赋给 ViewHolder 中对应的变量,就相当于先把它们装进一个容器,下次要用的时候,直接从容器中获取。然后可以对接受来的数据进行分段或者分页加载,也可以优化性能

Bitmap 的优化套路很简单,粗暴,就是让压缩 三种压缩方式:

  1. 对图片质量进行压缩
  2. 对图片尺寸进行压缩
  3. 使用 libjpeg.so 库进行压缩
响应速度优化

响应速度优化的核心思想是避免在主线程中做耗时操作,把耗时操作异步处理。

线程优化

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

其他优化
  1. 避免创建不必要的对象
  2. 首选静态(这里说的是特定情景) 如果您不需要访问对象的字段,请使您的方法保持静态。调用速度将提高约 15%-20%。这也是很好的做法,因为你可以从方法签名中看出,调用方法不能改变对象的状态
  3. 对常量使用 static final 此优化仅适用于基本类型和 String 常量,而不适用于 任意引用类型。尽管如此,static final 尽可能声明常量是一种好习惯。
  4. 使用增强的 for 循环语法 增强 for 循环(for-each)可用于实现 Iterable 接口和数组的集合。对于集合,分配一个迭代器来对 hasNext()和进行接口调用next()。使用一个 ArrayList,手写计数循环快约 3 倍,但对于其他集合,增强的for 循环语法将完全等效于显式迭代器用法。
  5. 避免使用浮点数 根据经验,浮点数比 Android 设备上的整数慢约 2 倍