Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS. ComposeUIViewController. Dispose composition on viewDidDisappear #747

Merged
merged 6 commits into from Aug 11, 2023

Conversation

elijah-semyonov
Copy link

@elijah-semyonov elijah-semyonov commented Aug 11, 2023

Proposed Changes

Revert memory leak fix PR
Implement eager dispose on viewDidDisappear, reconstruct scene on viewWillAppear

Testing

Test: same as reverted PR

API Changes

ComposeUIViewController now disposes the composition on viewDidDisappear and reconstructs it on viewWillAppear.
Clients should keep the important state outside of the composition and composition should subscribe to it:

class MyScreenState {
    var title by mutableStateOf("Title")
        private set
}

val state = MyScreenState()
val viewController = ComposeUIViewController {
    Text(state.title)
}

@elijah-semyonov elijah-semyonov changed the title Es/ios eager scene dispose Eagerly dispose and reconstruct ComposeScene on iOS Aug 11, 2023
@elijah-semyonov elijah-semyonov self-assigned this Aug 11, 2023
@elijah-semyonov elijah-semyonov marked this pull request as ready for review August 11, 2023 09:29
}

actual fun dispose() {
attachedComposeContext?.dispose()
Copy link
Collaborator

@igordmn igordmn Aug 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to add saving/restoring state via rememberSaveable, but it appears that Android doesn't save the state on attach/detach:

import android.os.Bundle
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.ComposeView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

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

        val view = ComposeView(this).apply {
            setContent {
                val savedState = rememberSaveable { Foo("Not saved") }
                var text by remember { mutableStateOf(savedState.text) }

                Column {
                    Text(text)

                    Button(
                        onClick = {
                            savedState.text = "Saved"
                            text = "Saved"
                        }
                    ) {
                        Text("Save")
                    }
                }
            }
        }
        setContentView(view)

        GlobalScope.launch(Dispatchers.Main) {
            delay(8000)
            setContentView(object : View(this@MainActivity) {})

            delay(2000)
            setContentView(view)
        }
    }
}

data class Foo(var text: String) : java.io.Serializable

Copy link
Collaborator

@igordmn igordmn Aug 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @dima-avdeev-jb , we now drop the Compose state when the UIViewController dissapears, and don't restore it when the controller appears. This is how Android behaves by default (see above). It also supports other cases via ViewCompositionStrategy, but we can support them later (if it is possible, there are complications).

Check also, the API Change section.

I will merge it now to build dev and beta02 faster. Let me know, if the change is needed to be explained.

@igordmn igordmn changed the title Eagerly dispose and reconstruct ComposeScene on iOS iOS. Dispose composition on viewDidDisappear Aug 11, 2023
@igordmn igordmn merged commit 3431324 into jb-main Aug 11, 2023
3 checks passed
@igordmn igordmn deleted the es/ios-eager-scene-dispose branch August 11, 2023 16:05
@igordmn igordmn changed the title iOS. Dispose composition on viewDidDisappear iOS. ComposeUIViewController. Dispose composition on viewDidDisappear Aug 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants