关于Hilt的运用,现在现已比较普及了,想必咱们现已知道。今日说的是一个如何使用Hilt来做一个发动结构的故事。
是否经历过大型项目的发动优化,一遍曩昔无任何效果,第二遍曩昔好几处报错,第三遍曩昔发动不了,第四遍曩昔回滚了代码 这都是为什么呢?
不要怀疑,不要询问,不是你技术菜,也不是逻辑有问题(当然没问题,有问题就不叫优化了,叫改bug),而是发动代码写的乱。
在咱们软件职业中,或者说每个人的人生中,乱 这一个字,让多少人痛不欲生,让多少人从成功走向了落寞,咳咳,让多少软件职业增本、让多少软件职业无利。
当你翻开Application 他的代码量是这样的:
你是不是很崩溃,咱们做发动优化的办法一般是,将能并发的并发,能拖延的拖延, 总之要快,要那种让女生瞧不起的快。可是面临这种代码,真的不敢动。
正文
在 发动优化一文中 我调研过图的发动优化办法
这种发动优化的办法理念是非常好的,今日我要做的操作是,处理乱代码,将初始化分隔做,在这个过程中,我发现能够使用配置引入协程,或有序、或并发、或依靠、或想怎样就怎样,简直爽到不可
使用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()
}
}
类图如下:
以下类和接口:
-
Application
:Android 应用程序类。 -
AppInitializer
接口:界说了一个init()
办法,该办法将在应用程序发动时调用,用于履行一些初始化使命。 -
EmojiInitializer
类:完结了AppInitializer
接口,用于初始化表情符号相关的内容 -
UtilsInitializers
类:完结了AppInitializer
接口,用于初始化一些实用工具。 -
AppInitializerEntryPoint
接口:界说了获取应用程序初始化器的办法,以及获取不同战略的应用程序初始化器列表的办法。 -
AppInitializersModule
类:运用 Dagger2 供给AppInitializerEntryPoint
接口的实例。 -
AppInitializerStrategy
枚举类:界说了应用程序初始化器的两种不同的战略:串行和并行。
以下联系:
-
Application
类与AppInitializerEntryPoint
接口之间的联系:Application
类运用AppInitializerEntryPoint
接口来获取应用程序初始化器。 -
AppInitializerEntryPoint
接口与AppInitializer
接口之间的联系:AppInitializerEntryPoint
接口运用AppInitializer
接口来表明应用程序初始化器。 -
AppInitializersModule
类与AppInitializerEntryPoint
接口之间的联系:AppInitializersModule
类供给了一个AppInitializerEntryPoint
接口的实例。 -
AppInitializersModule
类与AppInitializer
接口之间的联系:AppInitializersModule
类供给了一组AppInitializer
接口的实例。 -
EmojiInitializer
类和UtilsInitializers
类都完结了AppInitializer
接口,它们之间的联系经过完结联系表明。
完好流程
-
User
发动应用程序。 -
Application
类获取AppInitializerEntryPoint
接口的实例。 -
AppInitializerEntryPoint
接口运用AppInitializersModule
类供给的实例,获取一组应用程序初始化器。 -
AppInitializerEntryPoint
接口调用每个应用程序初始化器的init()
办法,按顺序履行初始化使命。 -
EmojiInitializer
类履行初始化表情符号的使命。 -
UtilsInitializers
类履行初始化实用工具的使命。
总结
很好的使用Hilt + 协程完结发动结构建立,完美处理代码乱,和初始化战略问题