Jetpack compose preview crashes with hiltViewModel<>()
Asked Answered
G

2

10

I use compose version 1.1.0-beta03 and hilt-navigation-compose:1.0.0-beta01. this is my Composable code:

fun EngagementBotChart(modifier: Modifier = Modifier) {
    val newHomeViewModel = hiltViewModel<HomeViewModel>()
    AndroidView(
        modifier = modifier.fillMaxSize(),
        factory = { context ->
            
        },
        update = { view ->
            
        }
    )
}

it works fine when I build the project but this is what occurs in compose preview:

java.lang.NoSuchMethodException: ir.inbo.app.home.viewmodel.HomeViewModel.<init>()
    at java.base/java.lang.Class.getConstructor0(Class.java:3349)
    at java.base/java.lang.Class.newInstance(Class.java:556)
    at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:87)
    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
    at ir.inbo.app.home.ui.HomeComponentsKt.EngagementBotChart(HomeComponents.kt:281)
    at ir.inbo.app.home.ui.ComposableSingletons$HomeComponentsKt$lambda-1$1$1$4$invoke$$inlined$ConstraintLayout$2.invoke(ConstraintLayout.kt:2424)
    at ir.inbo.app.home.ui.ComposableSingletons$HomeComponentsKt$lambda-1$1$1$4$invoke$$inlined$ConstraintLayout$2.invoke(ConstraintLayout.kt:101)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.ui.layout.LayoutKt.MultiMeasureLayout(Layout.kt:562)
    at ir.inbo.app.home.ui.ComposableSingletons$HomeComponentsKt$lambda-1$1$1$4.invoke(HomeComponents.kt:255)
    at ir.inbo.app.home.ui.ComposableSingletons$HomeComponentsKt$lambda-1$1$1$4.invoke(HomeComponents.kt:86)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at ir.inbo.app.home.ui.HomeComponentsKt.HomeBoxComponent(HomeComponents.kt:267)
    at ir.inbo.app.home.ui.ComposableSingletons$HomeComponentsKt$lambda-1$1$invoke$$inlined$ConstraintLayout$2.invoke(ConstraintLayout.kt:2413)
    at ir.inbo.app.home.ui.ComposableSingletons$HomeComponentsKt$lambda-1$1$invoke$$inlined$ConstraintLayout$2.invoke(ConstraintLayout.kt:101)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.ui.layout.LayoutKt.MultiMeasureLayout(Layout.kt:562)
    at ir.inbo.app.home.ui.ComposableSingletons$HomeComponentsKt$lambda-1$1.invoke(HomeComponents.kt:255)
    at ir.inbo.app.home.ui.ComposableSingletons$HomeComponentsKt$lambda-1$1.invoke(HomeComponents.kt:34)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.material.MaterialTheme_androidKt.PlatformMaterialTheme(MaterialTheme.android.kt:23)
    at androidx.compose.material.MaterialThemeKt$MaterialTheme$1$1.invoke(MaterialTheme.kt:82)
    at androidx.compose.material.MaterialThemeKt$MaterialTheme$1$1.invoke(MaterialTheme.kt:81)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.material.TextKt.ProvideTextStyle(Text.kt:265)
    at androidx.compose.material.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:81)
    at androidx.compose.material.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:80)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.material.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:72)
    at ir.inbo.app.theme.ThemeKt.InboTheme(Theme.kt:54)
    at ir.inbo.app.home.ui.HomeComponentsKt.HomeGrid(HomeComponents.kt:34)
    at ir.inbo.app.home.ui.HomeComponentsKt.HomeGridPreview(HomeComponents.kt:232)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at androidx.compose.ui.tooling.CommonPreviewUtils.invokeComposableMethod(CommonPreviewUtils.kt:150)
    at androidx.compose.ui.tooling.CommonPreviewUtils.invokeComposableViaReflection$ui_tooling_release(CommonPreviewUtils.kt:189)
    at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1$composable$1.invoke(ComposeViewAdapter.kt:578)
    at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1$composable$1.invoke(ComposeViewAdapter.kt:576)
    at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1.invoke(ComposeViewAdapter.kt:615)
    at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1.invoke(ComposeViewAdapter.kt:571)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.ui.tooling.InspectableKt.Inspectable(Inspectable.kt:61)
    at androidx.compose.ui.tooling.ComposeViewAdapter$WrapPreview$1.invoke(ComposeViewAdapter.kt:520)
    at androidx.compose.ui.tooling.ComposeViewAdapter$WrapPreview$1.invoke(ComposeViewAdapter.kt:519)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.ui.tooling.ComposeViewAdapter.WrapPreview(ComposeViewAdapter.kt:515)
    at androidx.compose.ui.tooling.ComposeViewAdapter.access$WrapPreview(ComposeViewAdapter.kt:121)
    at androidx.compose.ui.tooling.ComposeViewAdapter$init$3.invoke(ComposeViewAdapter.kt:571)
    at androidx.compose.ui.tooling.ComposeViewAdapter$init$3.invoke(ComposeViewAdapter.kt:568)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:410)
    at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:252)
    at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:251)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:166)
    at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:123)
    at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:122)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:114)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$3.invoke(Wrapper.android.kt:157)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$3.invoke(Wrapper.android.kt:156)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:156)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:140)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.ComposerKt.invokeComposable(Composer.kt:3337)
    at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2582)
    at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2571)
    at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:234)
    at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source)
    at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2571)
    at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:2522)
    at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:478)
    at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:748)
    at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:433)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:140)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
    at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:897)
    at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:131)
    at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:182)
    at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
    at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:196)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:138)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
    at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:984)
    at android.view.View.dispatchAttachedToWindow(View.java:20479)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3489)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
    at android.view.AttachInfo_Accessor.setAttachInfo(AttachInfo_Accessor.java:44)
    at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:360)
    at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:431)
    at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:141)
    at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:714)
    at com.android.tools.idea.rendering.RenderTask.lambda$inflate$7(RenderTask.java:870)
    at com.android.tools.idea.rendering.RenderExecutor$runAsyncActionWithTimeout$2.run(RenderExecutor.kt:187)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

when I delete the hiltviewModel code everything work fine! I try it with different versions of compose and I can't solve this problem!

Gt answered 21/11, 2021 at 9:35 Comment(5)
Does this answer your question? How to get preview in composable functions that depend on a view model?Katinakatine
Can't say anything without seeing the hilt modules and the view model. However does hiltViewModel() work elsewhere?Grosso
There are too many arguments in my view model that must be injected, with this solution I must write too much boilerplate code which is not good @PhilipDukhovGt
@Grosso hiltViewModel is working correctly anywhere, the issue is only in preview.Gt
@mobinyardim you don't have access to preview application, so you can't inject your dependencies. If you don't wanna write boilerplate, use preview only for views which are not depend on view models - you can de-composite you views to smaller once.Katinakatine
G
14

After some searching and reviewing of google sample codes here is the way you must follow to prevent the preview crashes:

Have a root composable for your screen and initial view model there, collect your data from viewModel as state (in case your data is flow) then pass data to content composable

@Composable
fun HomeScreen(
    navController: NavController
){
    val viewModel = hiltViewModel<HomeViewModel>()
    val someData by viewModel.someData.collectAsState()
}
@Composable
fun HomeScreenContent(
    someData: Type = defaultvalue
){
   //your UI codes
}

in preview use, HomeScreenContent instead of HomeScreen, and your problem will be solved!

thanks to @PhilipDukhov that helped in the comments

Gt answered 12/9, 2022 at 7:23 Comment(0)
I
0

Sometimes, your subview created with hiltViewModel.That you can make this subview create by a callback. The callback create same subview and preview function create by a preview subview.

@Composable
internal fun MainRouter(
...
onGeneragePage: @Composable (idx: Int) -> Unit = {idx ->
    when (idx) {
        MainTabs.Discover.ordinal -> DiscoverRoute() // with hiltViewModel
        MainTabs.Party.ordinal -> PartyRoute() // with hiltViewModel

        else -> DiscoverRoute()
    }
}
)

@Preview
@Composable
private fun PreMainScreen() {
    MainScreen(
        count = 0,
        onAddCount = {},
        onGeneragePage = {idx ->
            when (idx) {
                MainTabs.Discover.ordinal -> DefaultDiscoverScreen() // no hiltViewModel
                MainTabs.Party.ordinal -> DefaultPartyScreen()
                else -> DefaultDiscoverScreen()
            }
        }
    )
}
Illiquid answered 19/1, 2024 at 9:52 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.