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

复用ComposeView至WindowManager后组合功能失效的问题求助

复用ComposeView至WindowManager后组合功能失效的问题求助

我正在开发一个Android服务,通过WindowManager添加悬浮层视图,这个视图是用ComposeView创建的。我的目标是只创建一次ComposeView,之后按需添加或移除它,不用每次都重新创建。

但我遇到的问题是:第一次添加ComposeView时一切正常,但把它从WindowManager移除后再重新添加,组合功能就停止工作了——视图里没有任何动画,按钮点击也完全失效。

我尝试过管理LifecycleOwner和调整生命周期事件,但问题依然存在。

组合功能失效的演示

以下是我的代码:

class MyService2 : Service() {

    override fun onBind(intent: Intent?): IBinder? {
        TODO("Not yet implemented")
    }
    
    private val lifecycleOwner = MyLifecycleOwner()
    
    companion object {
        const val CHANNEL_ID = "ForegroundServiceChannel"
    }

    private val windowManager by lazy {

        applicationContext.getSystemService(WINDOW_SERVICE) as WindowManager
    }

    private val layoutPrams by lazy {
        WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            (WindowManager.LayoutParams.FLAG_FULLSCREEN
                    or WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE),
            PixelFormat.TRANSLUCENT
        )
    }
    
    override fun onCreate() {
        super.onCreate()
        lifecycleOwner.performRestore(null)
        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)

        createNotificationChannel()

        val notification = createNotification()
        startForeground(579, notification)

    }
    
    private fun addComposeView() {
        windowManager.addView(composeView, layoutPrams)
        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
    }
    
    private val composeView: ComposeView by lazy {
        ComposeView(this).apply {

            val viewModelStore = ViewModelStore()

            val viewModelStoreOwner = object : ViewModelStoreOwner{
                override val viewModelStore: ViewModelStore
                    get() =viewModelStore
            }

            setViewTreeLifecycleOwner(lifecycleOwner)
            setViewTreeSavedStateRegistryOwner(lifecycleOwner)
            setViewTreeViewModelStoreOwner(viewModelStoreOwner)

            setContent { ComposeView() }

        }

    }
    
    @Preview
    @Composable
    fun ComposeView() {
        Column(
            modifier = Modifier
        ) {
            
            Button(onClick = {
                windowManager.removeView(composeView)
                lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)

            }) {
                Text("Remove view")
            }
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)
        intent?.let {
            if (intent.getBooleanExtra("stop", false)) {
                stopSelf()
            } else if (intent.getBooleanExtra("add_compose", false)) {
                addComposeView()
            }

        }
        return START_STICKY
    }


    override fun onDestroy() {
        super.onDestroy()
        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    }

    private fun createNotification(): Notification {
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("My Foreground Service")
            .setContentText("Service is running in the foreground")
            .setSmallIcon(R.drawable.ic_android_black_24dp) // replace with your icon
            .build()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val serviceChannel = NotificationChannel(
                CHANNEL_ID,
                "Foreground Service Channel",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            val manager = getSystemService(NotificationManager::class.java)
            manager?.createNotificationChannel(serviceChannel)
        }
    }
}

private class MyLifecycleOwner : SavedStateRegistryOwner {

    private var mLifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
    private var mSavedStateRegistryController: SavedStateRegistryController = SavedStateRegistryController.create(this)
    
    override val lifecycle: Lifecycle
        get() = mLifecycleRegistry

    override val savedStateRegistry: SavedStateRegistry
        get() = mSavedStateRegistryController.savedStateRegistry
    
    val isInitialized: Boolean
        get() = true

    fun setCurrentState(state: Lifecycle.State) {
        mLifecycleRegistry.currentState = state
    }

    fun handleLifecycleEvent(event: Lifecycle.Event) {
        mLifecycleRegistry.handleLifecycleEvent(event)
    }

    fun performRestore(savedState: Bundle?) {
        mSavedStateRegistryController.performRestore(savedState)
    }

    fun performSave(outBundle: Bundle) {
        mSavedStateRegistryController.performSave(outBundle)
    }
}

我尝试过的方法

  • 调整添加/移除操作时的lifecycleOwner事件(ON_CREATE、ON_RESUME等)
  • 确认ComposeView只被创建一次并复用

到底是什么原因导致重新添加视图到WindowManager后组合功能失效?有没有特定的生命周期事件或者策略是我需要更好地管理的?

备注:内容来源于stack exchange,提问作者Ali Asjad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 02:54:34