java.lang.IllegalStateException:将 LiveData 观察为状态时,CompositionLocal LocalLifecycleOwner 不存在

问题描述 投票:0回答:1

当从视图模型观察 LiveData 作为 Activity onCreate 中的状态时,我得到了

IllegalStateException
。它抱怨缺少生命周期所有者,但是根据我的理解,observeAsState() 应该采用其所有者的生命周期,在本例中是活动。

以下是崩溃日志:

java.lang.IllegalStateException: CompositionLocal LocalLifecycleOwner not present
    at androidx.lifecycle.compose.LocalLifecycleOwnerKt$LocalLifecycleOwner$1.invoke(LocalLifecycleOwner.kt:26)
    at androidx.lifecycle.compose.LocalLifecycleOwnerKt$LocalLifecycleOwner$1.invoke(LocalLifecycleOwner.kt:25)
    at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
    at androidx.compose.runtime.LazyValueHolder.getCurrent(ValueHolders.kt:46)
    at androidx.compose.runtime.LazyValueHolder.readValue(ValueHolders.kt:48)
    at androidx.compose.runtime.CompositionLocalMapKt.read(CompositionLocalMap.kt:91)
    at androidx.compose.runtime.ComposerImpl.consume(Composer.kt:2366)
    at androidx.compose.runtime.livedata.LiveDataAdapterKt.observeAsState(LiveDataAdapter.kt:72)
    at com.example.testblockers.MainActivityKt.MyApp(MainActivity.kt:57)
    at com.example.testblockers.MainActivity$onCreate$1$1$1.invoke(MainActivity.kt:44)
    at com.example.testblockers.MainActivity$onCreate$1$1$1.invoke(MainActivity.kt:43)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
    at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:129)
    at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:113)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:362)
    at androidx.compose.material3.SurfaceKt.Surface-T9BRK9s(Surface.kt:110)
    at com.example.testblockers.MainActivity$onCreate$1$1.invoke(MainActivity.kt:43)
    at com.example.testblockers.MainActivity$onCreate$1$1.invoke(MainActivity.kt:42)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:362)
    at androidx.compose.material3.TextKt.ProvideTextStyle(Text.kt:261)
    at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:81)
    at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:80)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:362)
    at androidx.compose.material3.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:73)
    at com.example.testblockers.ui.theme.ThemeKt.TestBlockersTheme(Theme.kt:65)
    at com.example.testblockers.MainActivity$onCreate$1.invoke(MainActivity.kt:42)
    at com.example.testblockers.MainActivity$onCreate$1.invoke(MainActivity.kt:41)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
    at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:428)
    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:109)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:362)
    at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:186)

这是视图模型:

class MainViewModel : ViewModel() {
    private val _counterLiveData = MutableLiveData<Int>()

    // Expose LiveData as immutable
    val counterLiveData: LiveData<Int>
        get() = _counterLiveData

    init {
        // Initialize LiveData with default value
        _counterLiveData.value = 0
    }

    fun incrementCounter() {
        _counterLiveData.value = (_counterLiveData.value ?: 0) + 1
    }
}

这是我正在观察实时数据的活动:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            // Initialize ViewModel
            val viewModel: MainViewModel = viewModel()

            TestBlockersTheme {
                Surface(color = MaterialTheme.colorScheme.background) {
                    MyApp(viewModel)
                }
            }
        }
    }
}

@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MyApp(viewModel: MainViewModel) {
    // Observe the counterLiveData from the ViewModel
    val counterState by viewModel.counterLiveData.observeAsState(initial = 0)

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Counter App") }
            )
        },
        content = {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(16.dp),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = "Counter: $counterState",
                    style = MaterialTheme.typography.bodyMedium
                )
                Spacer(modifier = Modifier.height(16.dp))
                Button(onClick = { viewModel.incrementCounter() }) {
                    Text("Increment")
                }
            }
        }
    )
}

以下是 gradle 依赖项:

dependencies {
    implementation("androidx.core:core-ktx:1.13.0")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
    implementation("androidx.activity:activity-compose:1.9.0")
    implementation(platform("androidx.compose:compose-bom:2023.03.00"))
    implementation("androidx.compose.ui:ui")
    implementation("androidx.compose.ui:ui-graphics")
    implementation("androidx.compose.ui:ui-tooling-preview")
    implementation("androidx.compose.material3:material3")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
    androidTestImplementation("androidx.compose.ui:ui-test-junit4")
    debugImplementation("androidx.compose.ui:ui-tooling")
    debugImplementation("androidx.compose.ui:ui-test-manifest")
    // jsoup HTML parser library @ https://jsoup.org/
    implementation("org.jsoup:jsoup:1.17.2")
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
    implementation("androidx.compose.runtime:runtime-livedata:1.7.0-alpha07")
    implementation("androidx.lifecycle:lifecycle-runtime-compose:2.7.0")
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
}

有人熟悉这个问题吗?

android kotlin android-jetpack-compose android-livedata
1个回答
0
投票

您混合了来自不兼容的不同版本的撰写工件。

虽然您使用 Compose BOM

2023.03.00
,但您明确指定了
1.7.0-alpha07
的版本
androidx.compose.runtime:runtime-livedata
。只需删除运行时实时数据的版本,它将回退到 BOM 确定的版本,即
1.4.0
,您的代码将再次运行。

© www.soinside.com 2019 - 2024. All rights reserved.