大厂Android启动优化-2 框架篇DGAppStartup

4,907 阅读3分钟

对于大型App来说,启动任务多,任务依赖复杂。保障任务逻辑的单一性,解耦启动任务逻辑,合理利用多核CPU优势,提高线程运行效率是重点关注的问题。

所以启动框架核心核心的目的是解决两点:

  • 解决任务依赖问题,让单个任务职责更加清晰,代码更加优雅,可以建立启动规范、后续有利于维护。
  • 利用多核cpu,提高任务执行效率。

框架调研

解决任务依赖关系类似的框架现在开源的也有好几个。

A. Startup 现阶段只能建立有向无环图,不支持线程调度,网上介绍的文章也很多,了解后是无法真正使用到生产项目中。

B. Alpha 支持有向无环图,线程切换支持不够完美,导致无法支持异步等待,而且长期没有维护。

C. android-startup 支持完美的线程调度,满足基本的需求。

  • 但是整体设计稍显复杂和冗余;android-startup中的单个任务不管理图的节点依赖关系,在task manager内直接对任务依赖关系解析,通过BFS方法获得有向无环图的拓扑排序,然后将所有的任务丢到线程池内执行,通过任务waitCountDownLatch锁的方式等待前置依赖执行等待和唤醒;Alpha 通过双向链表的方式管理任务,最开始执行头部任务,当任务执行后通知后继节点,后继阶段判断当前依赖是任务是否全部完成来判断是否可以继续执行。
指标App StartupAndroid StartupDGAppStartup
手动配置
自动配置
依赖支持
闭环处理
线程控制
异步等待
依赖回调
耗时统计
线程优先级
多进程

依赖关系设计

依赖关系设计上整体都是通过向无环图方式,具体代码实现上参考Alpha设计。通过后继节点驱动任务运行,避免了拓扑排序等弊端。另外DGAppStartup未设计通过配置构建任务图,因为考虑配置首先需要解析,然后需要反射调用等。

建立有向无环图

image.png
1)类似链表的原理,每个任务节点建立一个后继任务节点的引用集合, 任务执行完成后通知后续节点运行。

image.png image.png

2)后继节点将会检查依赖任务是否全部完成,如果全部完成就执行当前任务。

image.png

依赖设置

依赖配置这块参考的是官方Startup方式,通过Class对应实例构建有向无环图。 image.png

提高任务执行效率

假设场景:ABCD四个任务,都必须在app create阶段执行完。在没有启动框架的情况下,需要把ABCD四个任务放置到主线程串行执行,但是有启动框架后可以通过将ABCD同时异步执行,通过锁等待方式控制四个任务完成后再执行下一步。

image.png

代码设计

通过新增isWaitOnMainThread属性,标记当前任务是否一定需要在这个阶段执行,然后计数所有标记属性的任务,主线程加上锁等待,然后每个任务完成后计算数量减去1,当计数为0的时候释放锁等待,然后主线程继续执行。

image.png

总结

该框架已经在过亿的App产品内上线,并已经稳定运行。整体的效果符合预期,单纯拆任务和配合线程调度,整体优化400ms。
框架:Github DGAppStartup

image.png

第三篇实战待续...