我的android项目中有两个模块,app模块和lib模块。
这两个模块都需要Koin进行D.I.,因此我在app模块的MyApplication
类中调用startKoin
,在lib模块中调用IninKointContentProvider
,如下所示。
// app module
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin(this, modules1)
}
}
// lib module
class InitKoinContentProvider : ContentProvider() {
override fun onCreate(): Boolean {
startKoin(context.applicationContext, modules2)
return true
}
}
然后应用程序崩溃并显示此消息
Caused by: org.koin.error.BeanOverrideException: Try to override definition with Single [class='android.content.Context'], but override is not allowed. Use 'override' option in your definition or module.
我猜startKoin
只能调用一次。
我找到的解决方案是合并两个koin模块,然后在MyApplication
中调用startKoin
,但我不喜欢这样。库模块可能被其他不使用koin的android项目导入,在这种情况下,我认为在InitKoinContentProvider
中调用startKoin
更好。
有解决这个问题的方法吗??谢谢!
6条答案
按热度按时间oyjwcjzk1#
@laalto的回答启发我找到了最好的解决方案,谢谢!
升级到koin2.0,然后使用KoinApplication和自定义的KoinComponent创建一个隔离的koin上下文,它可以让lib模块使用koin,而不需要app模块进行任何初始化调用,仍然在ContentProvider中启动koin,整个代码如下。
参考:https://insert-koin.io/docs/2.0/documentation/reference/index.html#_koin_context_isolation
2j4z5cfb2#
在库模块中,使用
loadKoinModules()
加载特定于模块的koin modules.docs。您需要在此之前运行
startKoin()
,因此内容提供程序的init顺序可能有点棘手。yyyllmsg3#
要在其他项目模块上初始化额外的koin模块,并且避免重复加载问题(例如,按home键,然后返回Activity),请转到您的模块声明文件:
那么根据你的观点:
w3nuxt5m4#
TL;DR在提供覆盖之前加载的模块所提供的依赖项时,请使用
override
参数设置为true
的single/factory
方法。当我为了UI测试而试图覆盖其中一个依赖项时,我遇到了类似的问题。
然后在
before
测试方法中:我在测试期间收到运行时异常:
org.koin.core.error.DefinitionOverrideException: Already existing definition or try to override an existing one
解决方案是向Koin表明您正在故意使用
single
函数的**override
**param来覆盖该依赖项,如下所示:2q5ifsrm5#
按照设计,
startKoin
是从Application类调用的。你可以在库中提供一个参数来决定是否调用startKoin
。但是我怀疑在库中包含Koin这样的东西是否是一个好的实践。如果一个应用程序已经包含Koin,但是版本不同呢?aor9mmx16#
这种方式对我来说非常有效:
并像往常一样在特性中定义模块: