【问题标题】:Handle Koin in base fragment (Module already loaded error)处理基础片段中的 Koin(模块已加载错误)
【发布时间】:2020-08-06 06:09:54
【问题描述】:

我有一个基本片段和另外 2 个片段,例如扩展基本片段的 fragmentOne、fragmentTwo。

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!

【问题讨论】:

    标签: android kotlin dependency-injection koin


    【解决方案1】:

    快速修复它

    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 是如何被引入片段堆栈的)。

    就个人而言,我会从片段中删除模块加载。但我不确定你为什么需要卸载它们。

    稍微好一点的方法

    我首先想到的是:

    1. 您创建了一个新的基于Activity 的类;
    2. onCreate 的这个类中你加载模块;
    3. 你展示你需要的片段,上下导航这个活动的片段的回栈;
    4. 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 类加载的。当您的应用程序运行时,您只能拥有一个有效的 Application 类实例。这意味着onCreate不会被调用两次,所以从Application#onCreate加载模块是安全的。

    或者,您可以从Activity 类的onCreate 加载模块,如上所述。 但请注意,在应用程序的生命周期中可以多次重新创建活动。

    【讨论】:

    • 我还在学习 Koin,你的解释很棒。卸载不需要的 koin 模块会提高应用程序的性能吗?我的想法是只加载我需要的任何东西,然后卸载它们以节省内存。如果我错了或者影响不大,也许我应该加载应用程序类中的所有内容并保留它。
    • “卸载不需要的 koin 模块可以提高应用程序的性能”——它可以。取决于模块的大小。在任何情况下,它都会释放一些内存。您的意图实际上是好的,但我认为如果您的应用程序很小或没有利用很多可用资源,这是一种开销。一些模块不会损害性能。如果出现以下情况,我会卸载模块:它们很少使用和/或创建起来很便宜,并且我需要这些额外的内存。如果您需要在将模块存储在 Koin 之前下载几 MB 的数据 - 您不应该删除它,恕我直言。每个案例都应该研究。
    • 感谢您的澄清,我将根据需要重新设计我的应用程序。
    猜你喜欢
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多