Koin 注入普通对象
本篇文章主要是看下对于 Compose,Koin 需要额外添加的依赖
implementation "io.insert-koin:koin-androidx-compose:3.4.5"
在 app 的build.gradle
文件中添加上面的依赖,将 koin-compose 添加到工程中。
下面我们来看看在@Composable
方法中如何注入一个普通的对象示例
注入基本对象
// 简单的一个日志输出类
class Logger {
fun print(msg: String) {
Log.d(TAG, "Logger print: $msg")
}
}
val module = module {
// 设置它的注入类型为单例
single { Logger() }
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
// 通过 koin 的 koinInject()方法进行对象注入
val logger: Logger = koinInject()
Text(
text = "Hello $name!",
modifier = modifier.clickable { logger.print("greeting") }
)
}
# 日志输出
Logger print: greeting
从上面的代码中可以看到,module{}
在普通工程和 compose 工程中用法是一致的,只是在获取依赖对象时,compose 中需要使用 koinInject()
方法来获取,此方法也是被@Composable
修饰,并且通过remember()
来完成内部逻辑实现。
由此可以看出,在 compose 中通过 koin 实现依赖注入也是非常简单的,而且内部实现也不复杂,接下来看看如何通过限定符获取不同场景的对象示例。
绑定限定符
koin 中可以使用qualifier
来限定同一个对象不同的实例注入,下面还是通过 Logger
对象来展示下限定符的作用。
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
// 通过获取对象时,增加限定符 qualifier 参数
val logger: Logger = koinInject(qualifier = qualifier("single1"))
val logger2: Logger = koinInject(qualifier = qualifier("single2"))
Text(
text = "Hello $name!",
modifier = modifier.clickable {
logger.print("greeting")
logger2.print("greeting")
}
)
}
class Logger {
fun print(msg: String) {
// 打印的地方增加了 hashcode 值,可以方便观察对象是否为同一个
Log.d(TAG, "Logger print: $msg, ${hashCode()}")
}
}
val module = module {
// 限定符为 single1
single(qualifier = qualifier("single1")) { Logger() }
// 限定符为 single2
single(qualifier = qualifier("single2")) { Logger() }
}
在 module
中,即使两个 Logger
对象都是采用单例模式,但是它们两个的限定符值不同,此时大家想一下是否会注入两个不同的单例对象呢,一会看下日志的输出就会明白了。同时我们在获取注入的对象时,也需要加上 qualifier
参数,不然在运行之后会抛出异常,koinInject()
方法的第一个参数就是 qualifier
,这里我们传入在 module
中定义过的限定符值即可。
Logger print: greeting, 105740997
Logger print: greeting, 63142938
通过日志就可以显而易见的看出,即使通过 single{}
来管理了依赖注入,但是在限定符的作用下, 获取的时候还是会根据限定符生成不同的对象实例。
这样我们在日常开发中就可以通过限定符来管理我们想要的注入对象了。
Koin 注入 ViewModel 对象
Koin 也帮助我们在使用 ViewModel
的过程中提供了依赖注入的便捷方式,无论是有参还是无参的 ViewModel
对象,对于 Koin 来说都为我们提供了便捷的操作。
我们先定义两个 ViewModel
对象,一个无参另外一个带有 Logger
参数的构造方法
class KoinViewModel : ViewModel() {
fun print() {
Log.d(TAG, "KoinViewModel print")
}
}
class KoinParamsViewModel(
private val logger: Logger
) : ViewModel() {
fun print() {
logger.print("KoinParamsViewModel")
}
}
然后在 moudle
中管理这两个注入的方式
val module = module {
single(qualifier = qualifier("single1")) { Logger() }
single(qualifier = qualifier("single2")) { Logger() }
viewModel { KoinViewModel() }
viewModel { KoinParamsViewModel(get(qualifier = qualifier("single1"))) }
}
无论是无参还是有参的 ViewModel
都是通过 viewModel{}
扩展函数来注入,只不过有参的直接通过 get()
方法将参数传入即可,这个在前面的文章中也有提到,注入对象的参数不需要在获取的时候传入,只需要在 module
定义的时候直接绑定就行了,这样就可以做到我们只管拿来用,不用去管如何实现的。
最后我们再来看看如何获取和使用注入的 ViewModel
@Composable
fun Greeting(
name: String, modifier: Modifier = Modifier,
koinViewModel: KoinViewModel = org.koin.androidx.compose.koinViewModel(),
koinParamsViewModel: KoinParamsViewModel = org.koin.androidx.compose.koinViewModel()
) {
Text(
text = "Hello $name!",
modifier = modifier.clickable {
koinViewModel.print()
koinParamsViewModel.print()
}
)
}
#
KoinViewModel print
Logger print: KoinParamsViewModel, 69574952
想要获取ViewModel
对象,只需要调用 koinViewModel()
方法就好,不用管是否有参数需要传递,Koin 会自动为我们将所需要的参数赋值过去,通过后面日志也可以表示我们 ViewModel
对象注入成功了。
其实在 Compose 工程中,Koin 只是简单的增加了一些特殊的注入方法,帮助我们更好的管理和使用注入对象,好了,到此为止 Koin 在 Compose 中如何使用依赖注入已经介绍完了,大家感兴趣的可以在 Demo 中体验体验下 Koin 的魅力!
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓
PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题