0

I am confused as to why this lateinit var koinApp is sometimes not initialized...

object MyKoin {
    lateinit var koinApp: KoinApplication
}

class Builder {
    init {
        MyKoin.koinApp = koinApplication {
            assertMainThread() // Succeeds
        }
    }

    fun build() = MyFragment()
}

class MyFragment()  : Fragment() {
    private val injectedProperty by MyKoin.koinApp.inject<Something>() // Sometimes crashes with "lateinit var MyKoin.koinApp not initialized"
}

And is used like this:

class TestFragment {
    private val rootViewId = View.generateViewId()

    override fun onCreate(savedInstanceState: Bundle?) {
        val myFragment = Builder.build()
        childFragmentManager.commit {
            replace(rootViewId, fragment)
        }
    }
}

There is absolutely no way that MyFragment is running the code injectedProperty before Builders init executes.... is there?

Thomas Cook
  • 4,371
  • 2
  • 25
  • 42
  • 1
    I think it could happen if your app is being restored and it brings you to where MyFragment is in the stack directly without first creating TestFragment. Then Builder will not have been instantiated yet. Why not make it `val koinApp = koinApplication { assertMainThread() }` and declare `MyKoin` in your Application's `onCreate()`? – Tenfour04 May 02 '23 at 14:26
  • Because the builder and MyFragment are part of a library, and I need an isolated koin context. – Thomas Cook May 02 '23 at 15:03
  • Based on the code you posted, you could just init a `Builder` in your application `onCreate`, which in turn would init the `koinApp` you need, along the lines of what @Tenfour04 suggested. – dominicoder May 02 '23 at 15:15
  • 2
    That said, I'd really question the use of this library - the little code you posted is already problematic (a "Builder" that initializes an application singleton in its constructor and then has a function to create a Fragment?) What? Why? – dominicoder May 02 '23 at 15:17
  • I am posting a minimum code to reproduce the issue, if I was to give you all the context about why I am doing this, it would take a lot more code and wouldn't improve the question at all. I'm not looking for advice on how to re-architect a library, I'm looking for advice on why this lateinit property could be in an un-itialized state given the example code. – Thomas Cook May 02 '23 at 15:21
  • I think my first comment describes that. I think we were maybe both anticipating the follow-up question, how to avoid the problem, then? – Tenfour04 May 02 '23 at 15:25
  • So you don't know the answer? That's ok, you can just say that :) – Thomas Cook May 02 '23 at 15:28
  • I followed the documentation of Koin itself to come to this solution by the way, but by all means, if you think you have a better way to use koin in a library, feel free to actually post an answer. https://insert-koin.io/docs/reference/koin-core/context-isolation – Thomas Cook May 02 '23 at 15:29
  • 1
    I described one way it could be happening, but I can't for certain say that's exactly why it's happening in your scenario because of the limited information I have about how your app works. That's why I wrote it as a comment and not an answer. The better way to use `koin` in a library, from what I can see (I have never used Koin), would be what I said in my first comment. Ask users of your library to declare `MyKoin` in Application's `onCreate` to ensure it is instantiated on the main thread. Every library that uses singletons that I know of has a similar instruction for using it. – Tenfour04 May 02 '23 at 16:04
  • There are 2 issues with this approach; users of the library shouldn't need to know about how the library performs it's DI (i.e. they users of a library shouldn't need to setup the DI instance for the library...) and I have already made sure that the library is instantiated on the main thread because I've asserted that. I understand you haven't used Koin before, but they don't document very well how to approach using it in a library, and all I have done is follow their documentation. They don't say to instantiate the singleton in the users application. – Thomas Cook May 03 '23 at 08:21

0 Answers0