koin icon indicating copy to clipboard operation
koin copied to clipboard

Koin 3.2.0 with Compose doesn't work with lazy viewModel.

Open ColaGom opened this issue 2 years ago • 3 comments

Describe the bug I just migrate koin version 3.1.5 to 3.2.0 then, I faced an exception as IllegalStateException. I could fix this issue by changing lazy to direct inject.

To Reproduce Steps to reproduce the behavior:

  1. On koin-core, koin-compose 3.2.0
  2. viewModel inject via lazy inline function

Code

class MyViewModel() : ViewModel // I declare empty implemenation viewmodel for testing

val viewModelModule = module {
    viewModelOf(::MyViewModel)
}

@Composable
fun MyComposableScreen() {
    val viewModel by viewModel<MyViewModel>() // crash
    val viewModel = getViewModel<MyViewModel>() // work fine
    ...
}

Expected behavior doesn't occur exception

Koin project used and used version (please complete the following information): koin-core version 3.2.0 koin-compose version 3.2.0 compose version 1.2.0-beta02 kotlin version 1.6.21

Crash report

java.lang.IllegalStateException: Compose Runtime internal error. Unexpected or incorrect use of the Compose internal runtime API (Start/end imbalance). Please report to Google or use https://goo.gle/compose-feedback
        at androidx.compose.runtime.ComposerKt.composeRuntimeError(Composer.kt:4237)
        at androidx.compose.runtime.ComposerImpl.finalizeCompose(Composer.kt:4383)
        at androidx.compose.runtime.ComposerImpl.endRoot(Composer.kt:1390)
        at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3201)
        at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3112)
        at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:573)
        at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:811)
        at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3705)
        at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:508)
        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:468)
        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:441)
        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:432)
        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:421)
        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(SubcomposeLayout.kt:732)
        at androidx.compose.material.ScaffoldKt$ScaffoldLayout$1$1$1.invoke(Scaffold.kt:316)
        at androidx.compose.material.ScaffoldKt$ScaffoldLayout$1$1$1.invoke(Scaffold.kt:243)
        at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:68)
        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure$1.placeChildren(SubcomposeLayout.kt:602)
        at androidx.compose.ui.node.LayoutNode$layoutChildren$1.invoke(LayoutNode.kt:960)
        at androidx.compose.ui.node.LayoutNode$layoutChildren$1.invoke(LayoutNode.kt:945)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutSnapshotReads$ui_release(OwnerSnapshotObserver.kt:52)
        at androidx.compose.ui.node.LayoutNode.layoutChildren$ui_release(LayoutNode.kt:945)
        at androidx.compose.ui.node.LayoutNode.onNodePlaced$ui_release(LayoutNode.kt:930)
        at androidx.compose.ui.node.InnerPlaceable.placeAt-f8xVGno(InnerPlaceable.kt:79)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
        at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50(Placeable.kt:370)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.placeOuterWrapper-f8xVGno(OuterMeasurablePlaceable.kt:161)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.access$placeOuterWrapper-f8xVGno(OuterMeasurablePlaceable.kt:28)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$placeAt$1.invoke(OuterMeasurablePlaceable.kt:149)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$placeAt$1.invoke(OuterMeasurablePlaceable.kt:148)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutModifierSnapshotReads$ui_release(OwnerSnapshotObserver.kt:59)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.placeAt-f8xVGno(OuterMeasurablePlaceable.kt:148)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
2022-05-23 17:28:01.424 7844-7844/com.linger.lingerstudio.aos E/AndroidRuntime:     at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50(Placeable.kt:370)
        at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50$default(Placeable.kt:203)
        at androidx.compose.foundation.layout.BoxKt.placeInBox(Box.kt:184)
        at androidx.compose.foundation.layout.BoxKt.access$placeInBox(Box.kt:1)
        at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1$measure$2.invoke(Box.kt:124)
        at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1$measure$2.invoke(Box.kt:123)
        at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:68)
        at androidx.compose.ui.node.LayoutNode$layoutChildren$1.invoke(LayoutNode.kt:960)
        at androidx.compose.ui.node.LayoutNode$layoutChildren$1.invoke(LayoutNode.kt:945)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutSnapshotReads$ui_release(OwnerSnapshotObserver.kt:52)
        at androidx.compose.ui.node.LayoutNode.layoutChildren$ui_release(LayoutNode.kt:945)
        at androidx.compose.ui.node.LayoutNode.onNodePlaced$ui_release(LayoutNode.kt:930)
        at androidx.compose.ui.node.InnerPlaceable.placeAt-f8xVGno(InnerPlaceable.kt:79)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer(Placeable.kt:393)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer$default(Placeable.kt:266)
        at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier$measure$1.invoke(GraphicsLayerModifier.kt:407)
        at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier$measure$1.invoke(GraphicsLayerModifier.kt:406)
        at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:68)
        at androidx.compose.ui.node.ModifiedLayoutNode.placeAt-f8xVGno(ModifiedLayoutNode.kt:101)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
        at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50(Placeable.kt:370)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.placeOuterWrapper-f8xVGno(OuterMeasurablePlaceable.kt:161)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.access$placeOuterWrapper-f8xVGno(OuterMeasurablePlaceable.kt:28)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$placeAt$1.invoke(OuterMeasurablePlaceable.kt:149)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$placeAt$1.invoke(OuterMeasurablePlaceable.kt:148)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutModifierSnapshotReads$ui_release(OwnerSnapshotObserver.kt:59)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.placeAt-f8xVGno(OuterMeasurablePlaceable.kt:148)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
        at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50(Placeable.kt:370)
        at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50$default(Placeable.kt:203)
        at androidx.compose.foundation.layout.BoxKt.placeInBox(Box.kt:184)
        at androidx.compose.foundation.layout.BoxKt.access$placeInBox(Box.kt:1)
        at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1$measure$2.invoke(Box.kt:124)
        at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1$measure$2.invoke(Box.kt:123)
        at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:68)
        at androidx.compose.ui.node.LayoutNode$layoutChildren$1.invoke(LayoutNode.kt:960)
2022-05-23 17:28:01.425 7844-7844/com.linger.lingerstudio.aos E/AndroidRuntime:     at androidx.compose.ui.node.LayoutNode$layoutChildren$1.invoke(LayoutNode.kt:945)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutSnapshotReads$ui_release(OwnerSnapshotObserver.kt:52)
        at androidx.compose.ui.node.LayoutNode.layoutChildren$ui_release(LayoutNode.kt:945)
        at androidx.compose.ui.node.LayoutNode.onNodePlaced$ui_release(LayoutNode.kt:930)
        at androidx.compose.ui.node.InnerPlaceable.placeAt-f8xVGno(InnerPlaceable.kt:79)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer(Placeable.kt:393)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer$default(Placeable.kt:266)
        at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier$measure$1.invoke(GraphicsLayerModifier.kt:407)
        at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier$measure$1.invoke(GraphicsLayerModifier.kt:406)
        at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:68)
        at androidx.compose.ui.node.ModifiedLayoutNode.placeAt-f8xVGno(ModifiedLayoutNode.kt:101)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer-aW-9-wM(Placeable.kt:396)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.placeOuterWrapper-f8xVGno(OuterMeasurablePlaceable.kt:163)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.access$placeOuterWrapper-f8xVGno(OuterMeasurablePlaceable.kt:28)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$placeAt$1.invoke(OuterMeasurablePlaceable.kt:149)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$placeAt$1.invoke(OuterMeasurablePlaceable.kt:148)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutModifierSnapshotReads$ui_release(OwnerSnapshotObserver.kt:59)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.placeAt-f8xVGno(OuterMeasurablePlaceable.kt:148)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeRelativeWithLayer(Placeable.kt:385)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeRelativeWithLayer$default(Placeable.kt:246)
        at androidx.compose.ui.layout.RootMeasurePolicy$measure$2.invoke(RootMeasurePolicy.kt:43)
        at androidx.compose.ui.layout.RootMeasurePolicy$measure$2.invoke(RootMeasurePolicy.kt:39)
        at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:68)
        at androidx.compose.ui.node.LayoutNode$layoutChildren$1.invoke(LayoutNode.kt:960)
        at androidx.compose.ui.node.LayoutNode$layoutChildren$1.invoke(LayoutNode.kt:945)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutSnapshotReads$ui_release(OwnerSnapshotObserver.kt:52)
        at androidx.compose.ui.node.LayoutNode.layoutChildren$ui_release(LayoutNode.kt:945)
        at androidx.compose.ui.node.LayoutNode.onNodePlaced$ui_release(LayoutNode.kt:930)
        at androidx.compose.ui.node.InnerPlaceable.placeAt-f8xVGno(InnerPlaceable.kt:79)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
2022-05-23 17:28:01.425 7844-7844/com.linger.lingerstudio.aos E/AndroidRuntime:     at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50(Placeable.kt:370)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.placeOuterWrapper-f8xVGno(OuterMeasurablePlaceable.kt:161)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.access$placeOuterWrapper-f8xVGno(OuterMeasurablePlaceable.kt:28)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$placeAt$1.invoke(OuterMeasurablePlaceable.kt:149)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$placeAt$1.invoke(OuterMeasurablePlaceable.kt:148)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutModifierSnapshotReads$ui_release(OwnerSnapshotObserver.kt:59)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.placeAt-f8xVGno(OuterMeasurablePlaceable.kt:148)
        at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:31)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeRelative(Placeable.kt:359)
        at androidx.compose.ui.layout.Placeable$PlacementScope.placeRelative$default(Placeable.kt:179)
        at androidx.compose.ui.node.LayoutNode.place$ui_release(LayoutNode.kt:803)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:278)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:38)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:208)
        at androidx.compose.ui.platform.AndroidComposeView.onMeasure(AndroidComposeView.android.kt:789)
        at android.view.View.measure(View.java:25466)
        at androidx.compose.ui.platform.AbstractComposeView.internalOnMeasure$ui_release(ComposeView.android.kt:298)
        at androidx.compose.ui.platform.AbstractComposeView.onMeasure(ComposeView.android.kt:285)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at com.android.internal.policy.DecorView.onMeasure(DecorView.java:747)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3397)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2228)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2486)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
2022-05-23 17:28:01.425 7844-7844/com.linger.lingerstudio.aos E/AndroidRuntime:     at android.view.Choreographer.doFrame(Choreographer.java:731)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

ColaGom avatar May 23 '22 08:05 ColaGom

I'm experiencing the same issue. Is there a way to lazy init so it doesnt crash?

PawelZarzycki avatar May 23 '22 20:05 PawelZarzycki

I have the same issue, the problem occurred when I migrated from Koin's version 3.2.0-beta-1 to 3.2.0. Just reverted back to the beta version and it seems to work again.

georgi-neykov-hub avatar May 25 '22 19:05 georgi-neykov-hub

I have the same issue in koin_version 3.2.0 and compose_version 1.1.1..

Lingga-MG avatar Jun 12 '22 05:06 Lingga-MG

I'm currently investigating on it 👍

arnaudgiuliani avatar Sep 01 '22 16:09 arnaudgiuliani

The root cause is that we are now using closely the ViewModel API from Google and it doesn't support any kind of Lazy or ViewModelLazy retuned type in Compose 1.1+

Best is to use the eager API: koinViewModel() or even get()

I will deprecate with error lazy APIs of koin-androidx-compose in 3.2.1

arnaudgiuliani avatar Sep 06 '22 09:09 arnaudgiuliani