在基本片段中处理 Koin(模块已加载错误)
Handle Koin in base fragment (Module already loaded error)
我有一个基本片段和另外 2 个片段,例如扩展基本片段的片段一、片段二。
abstract class BaseFragment(): Fragment(){
init{
loadKoinModules(listOf(sampleModules))
}
override fun onDestroyView() {
super.onDestroyView()
unloadKoinModules(listOf(sampleModules))
}
}
当我登陆 fragmentOne 时,koin 模块已加载,一切正常。我从 fragmentOne 导航到 fragmentTwo,在 unloadKoinModules 之前再次调用 loadKoinModules。我认为 fragmentOne 中加载的模块仍然存在,并且在为 fragmentTwo 加载模块之前不会被删除。加载和卸载 koin 模块的正确方法或生命周期是什么?
module 'org.koin.core.module.Module@87380fe' already loaded!
module 'org.koin.core.module.Module@cef805f' already loaded!
快速修复
abstract class BaseFragment(): Fragment(){
init{
// Making sure we do not get "module already loaded" error
unloadKoinModules(listOf(sampleModules))
loadKoinModules(listOf(sampleModules))
}
override fun onDestroyView() {
super.onDestroyView()
unloadKoinModules(listOf(sampleModules))
}
}
没有办法解决这个问题,因为 init
首先被调用,然后是 Fragment2 的 onCreateView
,然后是 Fragment1 的 onDestroyView
(并不总是被调用,取决于 Fragment2 的方式介绍到碎片堆栈)。
就个人而言,我会从片段中删除模块加载。但是我不确定你为什么需要卸载它们。
稍微好一点的方法
我首先想到的是:
- 您创建一个新的
Activity
基于 class;
- 在
onCreate
的 class 中加载模块;
- 你显示你需要的片段,上下导航this activity;
的片段返回栈
- 调用
Activity#onDestroy
时 - 卸载模块
class MyActivity: Activity {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loadKoinModules(listOf(sampleModules))
// load the first fragment
}
override fun onDestroy() {
super.onDestroy()
unloadKoinModules(listOf(sampleModules))
}
}
如何做得更好? (如果卸载可以去掉)
首先,确定你真的要卸载这些模块。为什么不让它们只加载一次然后离开?自己决定。
Koin 模块只能加载一次。一旦它们被加载,这些模块将在整个应用程序中可用。这意味着您不能加载同一个模块两次 - 没有必要。
在 Koin 官方示例中有一个专门针对 Android:
class MyApplication : Application() {
override fun onCreate(){
super.onCreate()
// start Koin!
startKoin {
// declare used Android context
androidContext(this@MyApplication)
// declare modules
modules(myModule)
}
}
}
正如我们所见,模块是从 Application
class 加载的。当您的应用程序是 运行 时,您只能有一个 Application
class 的有效实例。这意味着 onCreate
不会被调用两次,因此从 Application#onCreate
.
加载模块是安全的
或者,您可以从 Activity
class 的 onCreate
加载模块,如上所述。 但请注意,activity 可以在应用程序的生命周期内多次重新创建。
我有一个基本片段和另外 2 个片段,例如扩展基本片段的片段一、片段二。
abstract class BaseFragment(): Fragment(){
init{
loadKoinModules(listOf(sampleModules))
}
override fun onDestroyView() {
super.onDestroyView()
unloadKoinModules(listOf(sampleModules))
}
}
当我登陆 fragmentOne 时,koin 模块已加载,一切正常。我从 fragmentOne 导航到 fragmentTwo,在 unloadKoinModules 之前再次调用 loadKoinModules。我认为 fragmentOne 中加载的模块仍然存在,并且在为 fragmentTwo 加载模块之前不会被删除。加载和卸载 koin 模块的正确方法或生命周期是什么?
module 'org.koin.core.module.Module@87380fe' already loaded!
module 'org.koin.core.module.Module@cef805f' already loaded!
快速修复
abstract class BaseFragment(): Fragment(){
init{
// Making sure we do not get "module already loaded" error
unloadKoinModules(listOf(sampleModules))
loadKoinModules(listOf(sampleModules))
}
override fun onDestroyView() {
super.onDestroyView()
unloadKoinModules(listOf(sampleModules))
}
}
没有办法解决这个问题,因为 init
首先被调用,然后是 Fragment2 的 onCreateView
,然后是 Fragment1 的 onDestroyView
(并不总是被调用,取决于 Fragment2 的方式介绍到碎片堆栈)。
就个人而言,我会从片段中删除模块加载。但是我不确定你为什么需要卸载它们。
稍微好一点的方法
我首先想到的是:
- 您创建一个新的
Activity
基于 class; - 在
onCreate
的 class 中加载模块; - 你显示你需要的片段,上下导航this activity; 的片段返回栈
- 调用
Activity#onDestroy
时 - 卸载模块
class MyActivity: Activity {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loadKoinModules(listOf(sampleModules))
// load the first fragment
}
override fun onDestroy() {
super.onDestroy()
unloadKoinModules(listOf(sampleModules))
}
}
如何做得更好? (如果卸载可以去掉)
首先,确定你真的要卸载这些模块。为什么不让它们只加载一次然后离开?自己决定。
Koin 模块只能加载一次。一旦它们被加载,这些模块将在整个应用程序中可用。这意味着您不能加载同一个模块两次 - 没有必要。
在 Koin 官方示例中有一个专门针对 Android:
class MyApplication : Application() {
override fun onCreate(){
super.onCreate()
// start Koin!
startKoin {
// declare used Android context
androidContext(this@MyApplication)
// declare modules
modules(myModule)
}
}
}
正如我们所见,模块是从 Application
class 加载的。当您的应用程序是 运行 时,您只能有一个 Application
class 的有效实例。这意味着 onCreate
不会被调用两次,因此从 Application#onCreate
.
或者,您可以从 Activity
class 的 onCreate
加载模块,如上所述。 但请注意,activity 可以在应用程序的生命周期内多次重新创建。