Обработка коина в базовом фрагменте (ошибка уже загруженного модуля) - PullRequest
1 голос
/ 06 августа 2020

У меня есть базовый фрагмент и еще 2 фрагмента, например, fragmentOne, fragmentTwo, которые расширяют базовый фрагмент.

abstract class BaseFragment(): Fragment(){
    init{
        loadKoinModules(listOf(sampleModules))
    }

    override fun onDestroyView() {
        super.onDestroyView()
        unloadKoinModules(listOf(sampleModules))
    }
}

Когда я приземлился на fragmentOne, модули коинов загружаются, и все в порядке. Я перехожу от fragmentOne к fragmentTwo, loadKoinModules вызывается снова перед unloadKoinModules. Я думаю, что загруженные модули в fragmentOne все еще существуют и не удаляются перед загрузкой модулей для fragmentTwo. Каков правильный способ или жизненный цикл загрузки и выгрузки модулей коина?

module 'org.koin.core.module.Module@87380fe' already loaded!
module 'org.koin.core.module.Module@cef805f' already loaded!

1 Ответ

1 голос
/ 06 августа 2020

Чтобы исправить это быстро

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, затем onCreateView фрагмента 2, затем onDestroyView фрагмента 1 (и не всегда он вызывается, зависит от того, как 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 есть один специально для 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.

В качестве альтернативы вы можете загружать модули из onCreate вашего Activity класса, как упоминалось выше. Но имейте в виду, что активность может быть воссоздана несколько раз в течение жизненного цикла приложения.

...