Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.flowfoundation.wallet.page.browser.widgets.LilicoWebView
import com.flowfoundation.wallet.page.window.WindowFrame
import com.flowfoundation.wallet.utils.extensions.removeFromParent
import com.flowfoundation.wallet.utils.extensions.setVisible
import com.flowfoundation.wallet.utils.loge
import java.util.*

private val tabs = mutableListOf<BrowserTab>()
Expand All @@ -24,6 +25,7 @@ fun popBrowserTab(tabId: String) {
tab.webView.saveRecentRecord()

webViewContainer.removeWebView(tab.webView)
tab.webView.destroyWebView()

if (tabs.isEmpty()) {
releaseBrowser()
Expand Down Expand Up @@ -72,6 +74,11 @@ fun newAndPushBrowserTab(url: String? = null): BrowserTab? {
}

fun clearBrowserTabs() {
// Destroy each WebView before dropping the references. Without this the
// chromium-side resources (renderer process, GPU buffers, JS heap) stay
// alive until the GC happens to collect the wrapper, which is a major
// contributor to the OOM reports filed against ExploreFragment.
tabs.forEach { runCatching { it.webView.destroyWebView() }.onFailure { loge(it) } }
tabs.clear()
}

Expand Down Expand Up @@ -100,6 +107,23 @@ private fun cleanCallbacks() {
tabs.forEach { it.webView.setWebViewCallback(null) }
}

/**
* Standard cleanup sequence recommended by the Android WebView team. Skipping
* any of these steps tends to leave the renderer process or the chromium JS
* heap allocated, which shows up later as an OOM in an unrelated allocation.
*/
private fun LilicoWebView.destroyWebView() {
runCatching {
stopLoading()
setWebViewCallback(null)
loadUrl("about:blank")
clearHistory()
Comment on lines +117 to +120
removeFromParent()
removeAllViews()
destroy()
Comment on lines +119 to +123
}.onFailure { loge(it) }
}

class BrowserTab(
val id: String,
val webView: LilicoWebView,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import android.view.MenuItem
import com.flowfoundation.wallet.R
import com.flowfoundation.wallet.base.activity.BaseActivity
import com.flowfoundation.wallet.page.browser.widgets.LilicoWebView
import com.flowfoundation.wallet.utils.extensions.removeFromParent
import com.flowfoundation.wallet.utils.loge

class WebViewActivity : BaseActivity() {

Expand All @@ -20,6 +22,25 @@ class WebViewActivity : BaseActivity() {
}
}

override fun onDestroy() {
// Without an explicit destroy the chromium-side resources backing the
// WebView outlive this Activity and accumulate across launches. That
// leak is one of the contributors to the OOM crashes reported against
// browser-adjacent screens.
runCatching {
findViewById<LilicoWebView>(R.id.webview)?.let { web ->
web.stopLoading()
web.setWebViewCallback(null)
web.loadUrl("about:blank")
web.clearHistory()
Comment on lines +32 to +35
web.removeFromParent()
web.removeAllViews()
web.destroy()
}
}.onFailure { loge(it) }
super.onDestroy()
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> finish()
Expand Down
Loading