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
Conversation
} | ||
|
||
actual fun dispose() { | ||
attachedComposeContext?.dispose() |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
Proposed Changes
Revert memory leak fix PR
Implement eager dispose on
viewDidDisappear
, reconstruct scene onviewWillAppear
Testing
Test: same as reverted PR
API Changes
ComposeUIViewController
now disposes the composition onviewDidDisappear
and reconstructs it onviewWillAppear
.Clients should keep the important state outside of the composition and composition should subscribe to it: