使用 Koin 进行依赖注入时,Jetpack Compose Preview 不起作用

Jetpack Compose Preview not working when using Koin for Dependency Injection

提问人:Lukas Schüler 提问时间:5/31/2022 最后编辑:Lukas Schüler 更新时间:2/9/2023 访问量:3318

问:

我想在我的应用程序中使用 Jetpack Compose。我已经在使用 Koin 进行 DI。因为我的 BaseFragment 中有很多方便的方法,所以我想继承它并使用 compose 构建相应的视图。

现在的问题是,当在 BaseFragment 中使用 DI 并从中继承时,不会显示可组合项的预览,并出现以下错误消息:

Error Message in console of preview

并引发以下异常:

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)
    ...

我的 BaseFragment 看起来像这样

public abstract class BaseFragment {


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

而我继承的 Fragment 看起来像这样

class ComposeDemoFragment: BaseFragment() {
   ...

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

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

如果在不继承自 BaseFragment 的 Fragment 中使用完全相同的预览,则一切正常。我已经包含了“Koin for Compose”的依赖项,并尝试使用 CoKoin。在这一点上,我不知道如何处理错误消息,或者错误消息是否与实际问题几乎没有关系。

这是一个错误还是有办法绕过这个错误?

Android koin android-jetpack-compose-preview

评论


答:

2赞 Andrew Kelly 6/9/2022 #1

您的代码由 Android Studio 按原样运行,查看您的示例,您的代码中没有任何内容正在使用 Koin。但是,我猜这只是示例代码。@PreviewComposeDemoFragmentContent()

在我的应用程序中,我们将 koin 组件注入到我们的主组件中,这些组件在使用时会中断,我们遇到了与您看到的相同的错误。PrimaryTheme{ }@Preview

解决此问题的一种方法是为正在注入的字段提供默认值,然后将您的 koin 代码放入检查中,例如LocalInspectionMode

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
)

因此,您的预览将使用默认值,但您的实际应用将使用 koin 注入的值。

评论

1赞 Mister Smith 8/10/2022
显然,当函数位于 Activity 类中时,Android Studio 会尝试以某种方式编译该类。 OP 没有显示它,但他可能在 Activity 中有一个注入的成员。但是,由于 AndroidStudio 在渲染预览时不会运行整个应用程序,因此注入的成员为 null,并且会出现这些奇怪的错误。@Preview
1赞 Mister Smith 8/10/2022 #2

发生这种情况是因为您的函数位于 .而且你可能在那里有一个注入的成员。@PreviewActivity

将其移动到文件的根目录,在活动类之外,预览将毫无错误地呈现。