Compose视图状态变更时不重组问题排查求助
问题:ComposeOverlayView中Compose视图状态变更无法触发重组
我在研究Neo Launcher Feeder项目时,发现ComposeOverlayView中的Compose视图在状态变更时无法触发重组。我已修改onCreate方法中的setContent,并显式为该类添加LifecycleOwner接口,还实现了LifecycleOwner、SavedStateRegistryOwner、ViewModelStoreOwner等理论上可触发重组的接口,也尝试过相关解决方案,但问题仍未解决。
2024年1月9日更新:我在Compose的setContent中添加了生命周期观察者,发现该观察者并未被调用。
DisposableEffect(lifecycleOwner) { val observer = object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { Log.v(TAG,"onResume Compose") } } lifecycleOwner.lifecycle.addObserver(observer) onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } }
核心代码
/* * This file is part of Neo Feed * Copyright (c) 2023 Saul Henriquez <henriquez.saul@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package com.saulhdev.feeder.overlay import android.content.Context import android.os.Bundle import android.view.View import androidx.activity.OnBackPressedDispatcher import androidx.activity.OnBackPressedDispatcherOwner import androidx.activity.result.ActivityResultRegistry import androidx.activity.result.ActivityResultRegistryOwner import androidx.activity.setViewTreeOnBackPressedDispatcherOwner import androidx.appcompat.view.ContextThemeWrapper import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.platform.ComposeView import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry import androidx.lifecycle.ViewModelStore import androidx.lifecycle.ViewModelStoreOwner import androidx.lifecycle.setViewTreeLifecycleOwner import androidx.lifecycle.setViewTreeViewModelStoreOwner import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import androidx.savedstate.SavedStateRegistry import androidx.savedstate.SavedStateRegistryController import androidx.savedstate.SavedStateRegistryOwner import androidx.savedstate.setViewTreeSavedStateRegistryOwner import com.google.android.libraries.gsa.d.a.OverlayController import com.saulhdev.feeder.NFApplication import com.saulhdev.feeder.R import com.saulhdev.feeder.compose.pages.OverlayPage import com.saulhdev.feeder.theme.AppTheme import org.kodein.di.DI import org.kodein.di.DIAware import org.kodein.di.android.closestDI import org.kodein.di.compose.withDI class ComposeOverlayView(val context: Context) : OverlayController(context, R.style.AppTheme, R.style.WindowTheme), LifecycleOwner, SavedStateRegistryOwner, ViewModelStoreOwner, OnBackPressedDispatcherOwner, ActivityResultRegistryOwner, DIAware { private lateinit var rootView: View private lateinit var composeView: ComposeView private lateinit var navController: NavHostController private val lifecycleRegistry = LifecycleRegistry(this) override val lifecycle: Lifecycle get() = lifecycleRegistry override val onBackPressedDispatcher: OnBackPressedDispatcher get() = OnBackPressedDispatcher() private val savedStateRegistryController = SavedStateRegistryController.create(this) override val savedStateRegistry: SavedStateRegistry get() = savedStateRegistryController.savedStateRegistry private val parentDI: DI by closestDI() override val di: DI by DI.lazy { extend(parentDI) } init { savedStateRegistryController.performAttach() savedStateRegistryController.performRestore(null) lifecycleRegistry.currentState = Lifecycle.State.STARTED } override fun onCreate(bundle: Bundle?) { super.onCreate(bundle) rootView = View.inflate( ContextThemeWrapper(this, R.style.AppTheme), R.layout.compose_overlay, container ) lifecycleRegistry.currentState = Lifecycle.State.CREATED rootView.setViewTreeSavedStateRegistryOwner(this) rootView.setViewTreeLifecycleOwner(this) rootView.setViewTreeViewModelStoreOwner(this) rootView.setViewTreeOnBackPressedDispatcherOwner(this) composeView = rootView.findViewById(R.id.compose_view) composeView.setContent { navController = rememberNavController() AppTheme { var t by remember { mutableStateOf(false) } androidx.compose.material3.Surface { androidx.compose.material3.Button(onClick = { t = !t }) { androidx.compose.material3.Text(text = "Start: $t") } } } } } override fun onDestroy() { super.onDestroy() lifecycleRegistry.currentState = Lifecycle.State.DESTROYED } override fun onResume() { super.onResume() lifecycleRegistry.currentState = Lifecycle.State.RESUMED } override val viewModelStore: ViewModelStore get() = ViewModelStore() override val activityResultRegistry: ActivityResultRegistry get() = NFApplication.mainActivity!!.activityResultRegistry }
类似问题
- 在Service(悬浮窗)中如何使用Jetpack Compose
- InputMethodService搭配Jetpack Compose时,ComposeView报错:Composed into the View which doesn't propagate ViewTreeLifecycleOwner
内容的提问来源于stack exchange,提问作者Kochez
相关产品推荐
相关产品推荐

