question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Android library project - A Koin Application has already been started

See original GitHub issue

Koin project used and used version:

  • project: koin-android
  • version: 2.0.1
  • platform: Android

Bug Description

I am developing android-library project that uses Koin. The library should be used as a singleton and provides initialize method consuming Andorid Context in which Koin is initialized.

The library is initialized by user (let’s call it final app) in Application’s onCreate method.

It works as charm unless the final app uses Koin as well. In such case, the startKoin in android-library throws exception:

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 
     Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [type:Single,primary_type:'my.example.project.core.LibraryInstance']
        at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:61)
        at org.koin.core.instance.SingleDefinitionInstance.get(SingleDefinitionInstance.kt:40)
        at org.koin.core.definition.BeanDefinition.resolveInstance(BeanDefinition.kt:70)
        ... 
     Caused by: org.koin.core.error.KoinAppAlreadyStartedException: A Koin Application has already been started
        at org.koin.core.context.GlobalContext.start(GlobalContext.kt:51)
        at org.koin.core.context.GlobalContextKt.startKoin(GlobalContext.kt:71)
        at my.example.project.core.di.KoinContextProvider$koin$2.invoke(KoinContextProvider.kt:15)
        at my.example.project.core.di.KoinContextProvider$koin$2.invoke(KoinContextProvider.kt:10)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at my.example.project.core.di.KoinContextProvider.getKoin(KoinContextProvider.kt)
        at my.example.project.core.di.MyKoinComponent$DefaultImpls.getKoin(MyKoinComponent.kt:7)
        at my.example.project.core.LibraryInstanceImpl.getKoin(LibraryInstanceImpl.kt:14)
        at my.example.project.core.LibraryInstanceImpl.<init>(LibraryInstanceImpl.kt:74)
        at my.example.project.ExampleKoinApp$onCreate$1$1$1.invoke(ExampleKoinApp.kt:20)
        at my.example.project.ExampleKoinApp$onCreate$1$1$1.invoke(ExampleKoinApp.kt:11)

For sake of simplicity, the exception is a little shortened. I can provide full exception if necessary, but it seems like it is not allowed to call startKoin twice in an Android project?

Expected behavior

As basically any android-library can be using Koin in its internal implementation, shouldn’t it be independent and KoinApplication should be scoped?

To reproduce

  1. Create an Android project with two modules - app and library
  2. Configure koin-android dependency for both
  3. Add implementation project(':library') in app’s build.gradle
  4. In library project, create an object Library with method initialize consuming Android Context
  5. In app project, extend Application class and in its onCreate method, startKoin and then call Library.initialize
  6. The app should crash now

Support codes

class ExampleKoinApp : Application() {

    override fun onCreate() {
        super.onCreate()

        startKoin {
            androidContext(this@ExampleKoinApp)
            modules(...)
        }

        Library.initialize(this@ExampleKoinApp)
    }
}

object Library {

    private lateinit var appContext: Context

    val koin: Koin by lazy {
        startKoin {
            modules(...)
        }.koin
    }

    @Synchronized
    fun initialize(context: Context) {
        if (::appContext.isInitialized) return

        appContext = context.applicationContext
    }

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
nikhil-thakkarcommented, Feb 29, 2020

You can’t call startKoin twice in the GlobalContext. You have two options:

  1. Either use loadKoinModules
  2. Use a KoinApplication to isolate your lib scope.

Both the approaches are documented well here.

Read more comments on GitHub >

github_iconTop Results From Across the Web

A Koin Application has already been started - Stack Overflow
A common practice is to pair @Before setup with @After cleanup. You can call stopKoin() there so the next call to startKoin() works...
Read more >
Isolate Koin Within an Android Module | by Elye - Medium
Caused by: org.koin.core.error.KoinAppAlreadyStartedException: A Koin Application has already been started. We are not allowed to startKoin twice.
Read more >
Dependency Injection in Android With Koin - GeeksforGeeks
Koin is an efficient dependency injection framework, to whom we delegate the duty of instantiating various objects of an application.
Read more >
Modules - Koin
An instance is created only a request for its type has been done. We just have to declare list of used modules when...
Read more >
Kotlin dependency injection: Koin vs. Hilt - LogRocket Blog
Learn about the two most popular dependency injection libraries for ... Once your Hilt application has been initialized, we need to tell ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found