Hey :wave: I'm running into an issue where a WebVi...
# compose
f
Hey 👋 I'm running into an issue where a WebView needs to re-render every time the user navigates to another native screen and back. We have a single-activity architecture, so the WebView can't simply be paused and resumed. I've seen approaches that store the WebView in the ViewModel — detaching it from its parent before navigating away and reattaching it on return — but this still feels brittle and likely to leak memory. There's also the newer
retain
API, though its docs explicitly recommend against using it with Views. Is there a stable, recommended way to handle this?
p
Perhaps propagating the Activity lifecycle events to the JavaScript using the JavaScript interface bridge?
f
Mh this requires each frontend to be able to handle those events and restore a state. Not really flexibly and scalable approach in my opinion.
👍 1
p
You are right. For this scenario I don't know of a clean solution.
k
have you tried ?
Copy code
fun saveState(outState: android.os.Bundle) {
    webview.saveState(outState)
}

fun restoreState(inState: android.os.Bundle) {
    webview.restoreState(inState)
}
f
@Kyriakos WebView.saveState()/restoreState() only persist the back/forward navigation history, not the live in-memory state.
t
I'm using circuit and retaining the WebView in an echivalent
retain
. Not pretty but it does what i need. Not seen any memory issues, granted my app isn't WebView heavy and i have a full compose app with all the configChanges flags in the manifest. So even if i rotate or unfold a foldable the webview app state preserves since the activity doesn't get recreated.
Copy code
var innerWebView by rememberRetained {
    mutableStateOf<WebView?>(null)
}

AndroidView(
    factory = { context ->
        val webview = innerWebView
        if (webview?.context === context) {
            webview
        } else {
            WebView(context).also {
                innerWebView = it
            }
        }
    },
    update = {
    },
    modifier = Modifier
        .fillMaxSize(),
)
❤️ 1