likes
comments
collection
share

Hilt 和协程助力启动框架搭建:解决代码混乱和初始化策略问题

作者站长头像
站长
· 阅读数 43

关于Hilt的使用,目前已经比较普及了,想必大家已经知道。今天说的是一个如何利用Hilt来做一个启动框架的故事。

是否经历过大型项目的启动优化,一遍过去无任何效果,第二遍过去好几处报错,第三遍过去启动不了,第四遍过去回滚了代码 这都是为什么呢?

不要怀疑,不要询问,不是你技术菜,也不是逻辑有问题(当然没问题,有问题就不叫优化了,叫改bug),而是启动代码写的乱。

在我们软件行业中,或者说每个人的人生中, 这一个字,让多少人悲痛欲绝,让多少人从成功走向了落寞,咳咳,让多少软件行业增本、让多少软件行业无利。

当你打开Application 他的代码量是这样的:

Hilt 和协程助力启动框架搭建:解决代码混乱和初始化策略问题

Hilt 和协程助力启动框架搭建:解决代码混乱和初始化策略问题

正文

这种启动优化的方式理念是非常好的,今天我要做的操作是,解决乱代码,将初始化分开做,在这个过程中,我发现可以利用配置引入协程,或有序、或并发、或依赖、或想怎样就怎样,简直爽到不行

利用Hilt 搭建启动框架

  • 首先,使用接口约束初始化框架
// 后续都需要依赖此框架
interface AppInitializer {
    fun init()
}
  • 其次,将实现了此接口的初始化器,分开并连起来
class AppInitializers @Inject constructor(
    private val application: Application,
) {

    private val initializers: Set<AppInitializer> by lazy {
        EntryPointAccessors.fromApplication(application, AppInitializerEntryPoint::class.java)
            .getAppInitializers()
    }

    fun init() {
        for (initializer in initializers) {
            initializer.init()
        }
    }
}

提供一个初始化入口,此代码将在APPlication 中调用,我们使用Hilt注解完成Set<AppInitialize> 的收集,并且在Application中调用init时 启动初始化,注意 这个地方(init)可以将Set 变为Map,指定策略,实现“或有序、或并发、或依赖、或想怎样就怎样,简直爽到不行”

  • 最后,使用

Application 中调用

initializers.init()

Hilt 部分代码

@EntryPoint
@InstallIn(SingletonComponent::class)
interface AppInitializerEntryPoint {
    fun getAppInitializers(): Set<AppInitializer>
}

将所初始化器,分别注册到启动器中

@Module
@InstallIn(SingletonComponent::class)
object AppInitializersModule {
    @Provides
    fun provideAppInitializers(application: Application): Set<AppInitializer> {
        return setOf(
            EmojiInitializer(application),
            UtilsInitializers(application),
        )
    }
}

这个代码比较简单,这就完事了,将乱代码直接分离开了

制定策略

乱代码是分开了,但是其实用性只在编码层面,想要达到“或有序、或并发、或依赖、或想怎样就怎样,简直爽到不行”这种境界,还需要添加策略

修改注册器

fun getStrategyAppInitializers(): Map<AppInitializer.AppInitializerStrategy, List<AppInitializers>>

我们提供一个策略类

enum class AppInitializerStrategy {
    SERIAL,
    PARALLEL,
}

添加到总注册器:

@Provides
fun provideStrategyAppInitializers(application: Application): Map<AppInitializer.AppInitializerStrategy, List<AppInitializer>> {
    return mapOf(
        AppInitializer.AppInitializerStrategy.SERIAL to arrayListOf(EmojiInitializer(application)),
        AppInitializer.AppInitializerStrategy.PARALLEL to arrayListOf(UtilsInitializers(application)),
    )
}

然后在总的启动器中根据不同的策略配合协程一起使用:

strategyInitializers[AppInitializer.AppInitializerStrategy.SERIAL]?.forEach {
    it.init()
}

strategyInitializers[AppInitializer.AppInitializerStrategy.PARALLEL]?.forEach {
    MainScope().launch(Dispatchers.IO) {
        it.init()
    }
}

类图如下:

Hilt 和协程助力启动框架搭建:解决代码混乱和初始化策略问题

以下类和接口:

  1. Application:Android 应用程序类。
  2. AppInitializer 接口:定义了一个 init() 方法,该方法将在应用程序启动时调用,用于执行一些初始化任务。
  3. EmojiInitializer 类:实现了 AppInitializer 接口,用于初始化表情符号相关的内容
  4. UtilsInitializers 类:实现了 AppInitializer 接口,用于初始化一些实用工具。
  5. AppInitializerEntryPoint 接口:定义了获取应用程序初始化器的方法,以及获取不同策略的应用程序初始化器列表的方法。
  6. AppInitializersModule 类:使用 Dagger2 提供 AppInitializerEntryPoint 接口的实例。
  7. AppInitializerStrategy 枚举类:定义了应用程序初始化器的两种不同的策略:串行和并行。

以下关系:

  1. Application 类与 AppInitializerEntryPoint 接口之间的关系:Application 类使用 AppInitializerEntryPoint 接口来获取应用程序初始化器。

  2. AppInitializerEntryPoint 接口与 AppInitializer 接口之间的关系:AppInitializerEntryPoint 接口使用 AppInitializer 接口来表示应用程序初始化器。

  3. AppInitializersModule 类与 AppInitializerEntryPoint 接口之间的关系:AppInitializersModule 类提供了一个 AppInitializerEntryPoint 接口的实例。

  4. AppInitializersModule 类与 AppInitializer 接口之间的关系:AppInitializersModule 类提供了一组 AppInitializer 接口的实例。

  5. EmojiInitializer 类和 UtilsInitializers 类都实现了 AppInitializer 接口,它们之间的关系通过实现关系表示。

完整流程

Hilt 和协程助力启动框架搭建:解决代码混乱和初始化策略问题

  1. User 启动应用程序。
  2. Application 类获取 AppInitializerEntryPoint 接口的实例。
  3. AppInitializerEntryPoint 接口使用 AppInitializersModule 类提供的实例,获取一组应用程序初始化器。
  4. AppInitializerEntryPoint 接口调用每个应用程序初始化器的 init() 方法,按顺序执行初始化任务。
  5. EmojiInitializer 类执行初始化表情符号的任务。
  6. UtilsInitializers 类执行初始化实用工具的任务。

总结

很好的利用Hilt + 协程完成启动框架搭建,完美解决代码乱,和初始化策略问题

转载自:https://juejin.cn/post/7219229724958801976
评论
请登录