Keep the app alive when a WebView renderer dies

This commit is contained in:
AntsyLich
2026-10-12 13:56:32 +06:00
parent 6dffca1593
commit 649fc83ffa
4 changed files with 37 additions and 2 deletions
@@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.network.interceptor
import android.annotation.SuppressLint
import android.content.Context
import android.webkit.JavascriptInterface
import android.webkit.RenderProcessGoneDetail
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
@@ -13,12 +14,14 @@ import eu.kanade.tachiyomi.network.AndroidCookieJar
import eu.kanade.tachiyomi.util.system.isOutdated
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.CoroutineScope
import logcat.LogPriority
import okhttp3.Cookie
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.util.system.logcat
import tachiyomi.i18n.MR
import java.io.IOException
import java.util.concurrent.CountDownLatch
@@ -73,6 +76,7 @@ class CloudflareInterceptor(
var challengeFound = false
var cloudflareBypassed = false
var isWebViewOutdated = false
var isRenderProcessGone = false
val origRequestUrl = originalRequest.url.toString()
val headers = parseHeaders(originalRequest.headers)
@@ -140,6 +144,17 @@ class CloudflareInterceptor(
}
}
}
override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean {
// Not handling it kills the app, failing the bypass is enough
logcat(LogPriority.ERROR) {
"WebView renderer gone during Cloudflare bypass: crashed=${detail.didCrash()}, " +
"priority=${detail.rendererPriorityAtExit()}, url=$origRequestUrl"
}
isRenderProcessGone = true
latch.countDown()
return true
}
}
webview.loadUrl(origRequestUrl, headers)
@@ -148,12 +163,13 @@ class CloudflareInterceptor(
latch.awaitFor30Seconds()
executor.execute {
if (!cloudflareBypassed) {
// Only destroy can be called on a WebView whose renderer is gone
if (!cloudflareBypassed && !isRenderProcessGone) {
isWebViewOutdated = webview?.isOutdated() == true
}
webview?.run {
stopLoading()
if (!isRenderProcessGone) stopLoading()
destroy()
}
}