【发布时间】:2021-10-12 15:25:31
【问题描述】:
我有一个我打包和发布的 Android 库模块。这是不同应用程序的依赖项,有些使用 Koin,有些不使用,因此我想使用 Koin 的 context isolation。
按照文档,我添加了一个 koin 组件和上下文,如下所示:
internal object LocalKoinContext {
lateinit var koinApplication: KoinApplication
}
// Custom KoinComponent using the local instance & not the Global context
interface CustomKoinComponent : KoinComponent {
// override the used Koin instance to use the local koin application instance (LocalKoinContext.koinApplication)
override fun getKoin(): Koin = LocalKoinContext.koinApplication.koin
}
并像这样添加创建 koinApplication:
// Local Koin application instance
LocalKoinContext.koinApplication = koinApplication {
// use AndroidLogger as Koin Logger - default Level.INFO
androidLogger(Level.ERROR)
// use the Android context given there
androidContext(applicationContext)
// load properties from assets/koin.properties file
androidFileProperties()
// declare used modules
modules(theModule)
}
我有一个使用本地 Koin 组件中的视图模型的活动,我曾经在该活动的 onCreate 内实例化 koinApplication:
class FirstActivity : AppCompatActivity(),
CustomKoinComponent {
private val sharedViewModel by viewModel<MySharedViewModel>()
...
override fun onCreate(savedInstanceState: Bundle?) {
...
// Local Koin application instance
LocalKoinContext.koinApplication = koinApplication {
// use AndroidLogger as Koin Logger - default Level.INFO
androidLogger(Level.ERROR)
// use the Android context given there
androidContext(applicationContext)
// load properties from assets/koin.properties file
androidFileProperties()
// declare used modules
modules(theModule)
}
}
问题是我随机得到NoBeanDefFoundException
Caused by org.koin.core.error.NoBeanDefFoundException: No definition found for class:'my.package.name.MySharedViewModel'. Check your definitions!
at org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.java:264)
at org.koin.core.scope.Scope.resolveInstance(Scope.java:233)
at org.koin.core.scope.Scope.get(Scope.java:204)
at org.koin.androidx.viewmodel.factory.DefaultViewModelFactory.create(DefaultViewModelFactory.java:11)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at org.koin.androidx.viewmodel.ViewModelResolverKt.get(ViewModelResolverKt.java:23)
at org.koin.androidx.viewmodel.ViewModelResolverKt.resolveInstance(ViewModelResolverKt.java:12)
at org.koin.androidx.viewmodel.scope.ScopeExtKt.getViewModel(ScopeExtKt.java:86)
at org.koin.androidx.viewmodel.scope.ScopeExtKt.getViewModel(ScopeExtKt.java:72)
at org.koin.androidx.viewmodel.ext.android.ViewModelStoreOwnerExtKt.getViewModel(ViewModelStoreOwnerExtKt.java:68)
at org.koin.androidx.viewmodel.ext.android.ViewModelStoreOwnerExtKt.getViewModel$default(ViewModelStoreOwnerExtKt.java:58)
at my.package.name.FirstActivity$special$$inlined$viewModel$default$1.invoke(FirstActivity.java:75)
我怀疑这是因为有时 koinApplication 没有时间自行设置,但由于这种情况很少见,我无法重现该问题。
在this stack question 的回答中,开发人员创建了一个ContentProvider 来实例化koinApplication。我已经尝试过了,到目前为止一切都很好(虽然,我只会在几个月后知道),但这真的是要走的路吗?必须为此创建内容提供者似乎有点过头了。
谁能阐明我们应该在哪里实例化本地KoinApplication?
【问题讨论】:
-
我不能说我自己已经完成了这个,但是堆栈跟踪表明视图模型没有在你的模块中设置,所以你可能想在问题中包含这些。此外,鉴于您的类的命名,您可能希望使用
by sharedViewModel委托而不是by viewModel -
另外——根据你的实际目标,你可能会发现使用 Scopes 是一条阻力较小的路径——仍然允许你使用传统的全局
startKoin并提供我认为你的封装寻找insert-koin.io/docs/reference/koin-android/scope -
@lase 视图模型在模块中,否则它根本无法工作。关于
by sharedViewModel或by viewModelthe docs are pretty clear about it的使用。它是一个库,打包为依赖项,并在不同的应用程序中使用,这一事实使得 Scopes 的使用变得更加棘手。也许我做错了,但我无法让使用和不使用 Koin 的应用程序很好地处理它们。我很想看到一个例子来说明它是如何工作的。