布局优化
- 如果父控件有颜色,也是自己需要的颜色,那么就不必在子控件加背景颜色
- 如果每个自控件的颜色不太一样,而且可以完全覆盖父控件,那么就不需要再父控件上加背景颜色
- 尽量减少不必要的嵌套
- 能用 LinearLayout 和 FrameLayout,就不要用 RelativeLayout,因为 RelativeLayout 控件相对比较复杂,测绘也想要耗时。
- 使用 include 和 merge 增加复用,减少层级
- ViewStub 按需加载,更加轻便
- 复杂界面可选择 ConstraintLayout,可有效减少层级
绘制优化
- onDraw 中不要创建新的局部对象
- onDraw 方法中不要做耗时的任务
内存优化
- 集合类泄漏
- 单例/静态变量造成的内存泄漏
- 匿名内部类/非静态内部类
- 资源未关闭造成的内存泄漏
- 网络、文件等流忘记关闭
- 手动注册广播时,退出时忘记 unregisterReceiver()
- Service 执行完后忘记 stopSelf()
- EventBus 等观察者模式的框架忘记手动解除注册
启动速度优化
- 利用提前展示出来的 Window,快速展示出来一个界面
- 避免在启动时做密集沉重的初始化
- 避免 I/O 操作、反序列化、网络操作、布局嵌套等
包体积优化
- 我们可以开启资源压缩,自动删除无用的资源
- 重用资源
- 能自己用 XML 写 Drawable
- 压缩 PNG 和 JPEG 文件
- 使用 WebP 文件格式
- 使用矢量图形
- 代码混淆
- 插件化
耗电优化
-
使用 JobScheduler 调度任务
-
使用懒惰法则
减少 你的应用程序可以删除冗余操作吗?例如,它是否可以缓存下载的数据而不是重复唤醒无线电以重新下载数据?
推迟 应用是否需要立即执行操作?例如,它可以等到设备充电才能将数据备份到云端吗?
合并 可以批处理工作,而不是多次将设备置于活动状态吗?例如,几十个应用程序是否真的有必要在不同时间打开收音机发送邮件?在一次唤醒收音机期间,是否可以传输消息?
ListView 和 Bitmap 优化
针对 ListView 优化,主要是合理使用 ViewHolder。创建一个内部类 ViewHolder,里面的成员变量和 view 中所包含的组件个数、类型相同,在 convertview 为 null的时候,把 findviewbyId 找到的控件赋给 ViewHolder 中对应的变量,就相当于先把它们装进一个容器,下次要用的时候,直接从容器中获取。然后可以对接受来的数据进行分段或者分页加载,也可以优化性能
Bitmap 的优化套路很简单,粗暴,就是让压缩 三种压缩方式:
- 对图片质量进行压缩
- 对图片尺寸进行压缩
- 使用 libjpeg.so 库进行压缩
响应速度优化
响应速度优化的核心思想是避免在主线程中做耗时操作,把耗时操作异步处理。
线程优化
线程优化的思想是采用线程池,避免在程序中存在大量的 Thread。线程池可以重用内部的线程,从而避免了现场的创建和销毁所带来的性能开销,同时线程池还能有效地控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象发生。
其他优化
- 避免创建不必要的对象
- 首选静态(这里说的是特定情景) 如果您不需要访问对象的字段,请使您的方法保持静态。调用速度将提高约 15%-20%。这也是很好的做法,因为你可以从方法签名中看出,调用方法不能改变对象的状态
- 对常量使用 static final 此优化仅适用于基本类型和 String 常量,而不适用于 任意引用类型。尽管如此,static final 尽可能声明常量是一种好习惯。
- 使用增强的 for 循环语法 增强 for 循环(for-each)可用于实现 Iterable 接口和数组的集合。对于集合,分配一个迭代器来对 hasNext()和进行接口调用next()。使用一个 ArrayList,手写计数循环快约 3 倍,但对于其他集合,增强的for 循环语法将完全等效于显式迭代器用法。
- 避免使用浮点数 根据经验,浮点数比 Android 设备上的整数慢约 2 倍