Initializer - 注解+协程实现的初始化启动库

552 阅读3分钟

项目地址: github.com/lwj1994/ini…

前言

Android 启动时有一些初始化的任务(初始化 SDK/ 自己的业务逻辑),项目小的时候,直接放在 Application 中初始化没什么毛病,但是项目大了之后,各种各样的初始化全写在一起就比较混乱,并且这些任务有依赖关系,B 任务需要等 A 任务初始化完成后才能初始化。

一般的做法是使用有向无环图来组织任务的依赖关系,Android 已经有很多成熟的库:

在对 App 进行初始化优化时,我发现大部分的框架,对于初始化的配置有点繁琐,站在用户的角度来说,使用者关心的只有

  • 如何组织任务的依赖关系(可以通过注解实现)
  • 如何调用触发任务启动 (手动一行代码)
  • 任务启动/结束的回调 (启动时传一个 callback)
  • 任务在哪个线程运行 (协程负责)

于是我想到用注解(易用)+协程(管理多线程)的方式来写一个框架,在 github 无意间发现 github.com/wurensen/Ta… 这个项目,作者的实现思路非常好,于是 fork 此库实现了 initializer

注解

注解的实现参考了 Room 和 johnsonlee/initializr

@Database(  
    entities = [DiyCloudConfiguration::class, GithubConfiguration::class, CodingConfiguration::class, GiteeConfiguration::class, UCloudConfiguration::class],  
    version = DB_CLOUD_VERSION,  
    exportSchema = true  
)  
abstract class CloudDataBase : RoomDatabase()

Room 通过 @Database 注解组织了当前数据库包含的表(entities)。

所以我们照猫画虎:

@Initialization(  
    tasks = [Task1::class,Task2::class,Task3::class,Task4::class])  
abstract class AppInitializer : Initializer()

这样来表示一个初始化中包含的所有任务。

同样的 Task 的依赖关系也可以通过注解实现:

@Task(dependencies = [Task1::class])  
class Task2 : InitializeTask(){
	override suspend fun initialize(context: InitializeContext) {  
    withContext(Dispatchers.IO) {  
        delay(1000)  
        println("executed completely")  
    }  
}

协程

Task 中的 initialize 方法是协程挂起方法,在这个方法自由选择切线程完成任务。

默认是通过 Dispathers.Main 启动,也通过 socpe 参数改变;通过 WithContext 自由切换。至于线程的优先级,则完全可以通过自定义 Dispather 来自定义。这部分属于线程管理,初始化框架按理也不需要管这些。

启动

initializer 通过反射(从易用性来说,这点性能可以忽略不计)创建 Initializer 实例:

// 创建初始化
val appInitializer = Initializer.Builder(AppInitializer::class.java).build()


// 开始启动任务
appInitializer.init(context = appContext, scope = launchScope, debug = true)

启动时的参数:

  • context: Context
  • scpoe: 协程启动运行的 scope
  • debug: debug

debug 为 true 时会检查当前的任务是否是正确的有向无环图(无环),release 为了性能则不检查。

回调

每个任务开始执行和结束执行都会回调,方便做一些 hook 操作。

  initializerA.init(this, debug = true, callback = object : Callback {
				// 初始化开始启动(第一个任务开始启动)
                override fun onInitializationStart(firstTask: InitializeTask) {
                    log("onInitializationStart, first is ${firstTask::class.qualifiedName}")
                }
				// 任务开始启动
                override fun onTaskStart(task: InitializeTask) {
                    log("onTaskStart ${task::class.qualifiedName}, dependency ${task.dependencies.toList()}")
                }
				// 任务结束
                override fun onTaskComplete(task: InitializeTask, timeConsuming: Long) {
                    log("onTaskComplete ${task::class.qualifiedName}, dependency ${task.dependencies.toList()}, timeConsuming = $timeConsuming ms")
                }

				// 全部初始化结束(最后一个任务结束)
                override fun onInitializationComplete(
                    lastTask: InitializeTask,
                    totalTimeConsuming: Long
                ) {
                    log("onInitializationComplete, $totalTimeConsuming ms, lastTask is ${lastTask::class.qualifiedName}")
                }

            })