You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:57:54