skip to Main Content

I want to use Jetpack Compose in my App. I am already using Koin for DI. Because I have a lot of convenience methods in my BaseFragment I want to inherit from it and build the corresponding view with compose.

Now the Problem is that when using DI in the BaseFragment and inheriting from it the preview of the composable wont be shown and following error Message appears:

Error Message in console of preview

and following exception is thrown:

java.lang.IllegalStateException: KoinApplication has not been started
    at org.koin.core.context.GlobalContext.get(GlobalContext.kt:36)
    at org.koin.java.KoinJavaComponent.getKoin(KoinJavaComponent.kt:122)
    at org.koin.java.KoinJavaComponent.get(KoinJavaComponent.kt:87)
    at org.koin.java.KoinJavaComponent.get$default(KoinJavaComponent.kt:81)
    at org.koin.java.KoinJavaComponent.get(KoinJavaComponent.kt)
    ...

My BaseFragment looks something like this

public abstract class BaseFragment {


    private final ActiveViewIdInteractor activeViewIdInteractor =
            new ActiveViewIdInteractor(KoinJavaComponent.get(ActiveViewIdService.class));
...

and my Fragment which inherits looks something like this

class ComposeDemoFragment: BaseFragment() {
   ...

   @Composable
    fun ComposeDemoFragmentContent() {
        Text(text = "Hello World",
            Modifier
                .fillMaxWidth()
                .background(Color.Cyan)
        )
    }

    @Preview
    @Composable
    private fun Preview() {
        ComposeDemoFragmentContent()
    }

If using the exact same preview in a Fragment which doesn’t inherit from BaseFragment everything works fine. I already included the dependency for "Koin for Compose" and also tried using CoKoin. At this Point I don’t know what to do with the error Message or if the error Message is even barely related to the actual Problem.

Is this a Bug or is there a way to bypass this error?

2

Answers


  1. Your @Preview code is being run as-is by Android Studio, looking at your example there is nothing in your ComposeDemoFragmentContent() that is using Koin. However, I’m guessing this is just sample code.

    In my app we inject koin components into our main PrimaryTheme{ } which used to break when used with @Preview, we got the same error as you’re seeing.

    One way around this is to provide a default value to the field being injected, and then put your koin code inside a check for LocalInspectionMode e.g.

    val someField = remember { mutableStateOf("Default")}
    
    if (!LocalInspectionMode.current) {
      // We're _not_ executing in an Android Studio Preview.
    
      // Use your injected Koin instance here e.g.
      val myUseCase: CustomUseCase = get()
      someField.value = myUseCase.getSomeValue()         
    }
    
    Text(
      text = someField.value
    )
    
    

    So your previews will use the default value, but your real app will use the koin injected value.

    Login or Signup to reply.
  2. This happens because your @Preview function is inside your Activity. And you probably have an injected member there.

    Move it to the root of the file, outside the activity class, and the preview will be rendered without errors.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search