WebView exécute son contenu Web dans un processus de moteur de rendu distinct. Il peut arriver que ce processus soit arrêté. Cela se produit si le système arrête le moteur de rendu pour libérer de la mémoire ou si le processus lui-même plante. Si vous ne gérez pas ces arrêts, votre application se fermera également.
Pourquoi la gestion de l'arrêt du processus est essentielle
Dans les versions antérieures d'Android, les utilisateurs étaient moins susceptibles de remarquer un problème lorsqu'une application ne parvenait pas à gérer l'arrêt du processus de moteur de rendu. Toutefois, les versions plus récentes d'Android utilisent des mécanismes plus complexes pour gérer la consommation de ressources des processus en arrière-plan. Par conséquent, si votre application n'implémente pas de gestionnaire pour
onRenderProcessGone, il est désormais plus probable que les utilisateurs observent des arrêts visibles au premier plan lorsqu'ils reviennent à l'application. L'implémentation de l'API de gestion des arrêts est nécessaire pour que votre application récupère correctement et offre une expérience utilisateur stable.
Utiliser l'API de gestion des arrêts
Vous pouvez gérer ces situations en remplaçant onRenderProcessGone dans votre WebViewClient.
Conditions requises pour la récupération
Pour que votre application continue de s'exécuter après l'arrêt d'un processus de moteur de rendu, chaque WebView de votre application doit respecter les règles suivantes :
- Ne réutilisez pas l'instance WebView. Une fois le moteur de rendu disparu, cet objet WebView spécifique est inutile. Vous devez supprimer l'objet WebView de votre hiérarchie des vues, le détruire et effacer toutes les références à celui-ci dans votre activité ou votre fragment pour éviter de continuer à appeler accidentellement des méthodes sur l'instance WebView détruite.
- Créez une instance. Si vous souhaitez continuer à afficher du contenu Web, vous avez besoin d'une nouvelle instance WebView.
- Renvoie la valeur "true". Votre implémentation doit renvoyer la valeur
truepour indiquer au code WebView que vous avez géré la situation. Si unWebViewutilisant ce processus de moteur de rendu ne renvoie pas la valeurtrue, WebView arrête ou plante votre application en fonction de la raison de la sortie du processus de moteur de rendu.
Exemple de mise en œuvre
L'exemple suivant montre comment gérer ces arrêts dans une activité complète. Il utilise detail.didCrash() pour enregistrer si le processus a planté ou si le système a arrêté le moteur de rendu pour libérer de la mémoire. Quelle que soit la cause, le
code nettoie en supprimant le WebView mort de la mise en page, en le détruisant,
et en effaçant les références de l'activité pour éviter NullPointerException.
Il prépare ensuite une nouvelle instance et renvoie la valeur true pour que l'application ne se ferme pas.
Remarque : L'exemple suivant renvoie toujours la valeur true pour que l'application continue de s'exécuter.
Si vous souhaitez spécifiquement que votre application s'arrête lorsque le moteur de rendu WebView s'arrête, vous pouvez renvoyer la valeur false à partir de ce rappel. Toutefois, nous vous recommandons de gérer la recréation et de renvoyer la valeur true pour une expérience utilisateur stable.
class MyWebViewActivity : AppCompatActivity() {
private var webViewContainer: ViewGroup? = null
private var myWebView: WebView? = null
private var crashCount = 0
private val MAX_CRASHES = 3
// NEW FLAG: Tracks if the WebView crashed while the activity was hidden
private var isWebViewPendingRecovery = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my_web_view)
webViewContainer = findViewById(R.id.my_web_view_container)
initWebView()
}
// NEW LIFECYCLE HOOK: Triggers when the user brings the app back to the foreground
override fun onResume() {
super.onResume()
// If a crash happened in the background, rebuild it now that the user can see it
if (isWebViewPendingRecovery) {
isWebViewPendingRecovery = false
Log.i("MY_APP_TAG", "Activity resumed. Recovering pending WebView now.")
recoverWebView()
}
}
private fun initWebView() {
val webView = WebView(this)
myWebView = webView
webViewContainer?.addView(webView)
webView.webViewClient = object : WebViewClient() {
override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean {
if (detail.didCrash()) {
Log.e("MY_APP_TAG", "The WebView rendering process crashed!")
} else {
Log.e("MY_APP_TAG", "System killed the WebView rendering process to reclaim memory.")
}
// Safely clean up the dead WebView
webViewContainer?.removeView(webView)
webView.destroy()
myWebView = null
// MODIFIED LOGIC: Check the lifecycle state of the Activity
// lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED) means the activity is visible and active
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
Log.i("MY_APP_TAG", "Activity is in foreground. Recovering immediately.")
recoverWebView()
} else {
// The app is in the background. Mark it for later!
Log.w("MY_APP_TAG", "Activity is in background. Postponing recovery until user returns.")
isWebViewPendingRecovery = true
}
return true
}
}
webView.loadUrl("https://www.example.com")
}
// HELPER FUNCTION: Extracted the recovery logic to reuse it
private fun recoverWebView() {
if (crashCount < MAX_CRASHES) {
crashCount++
Log.w("MY_APP_TAG", "Recovering WebView... Attempt $crashCount")
initWebView()
} else {
Log.e("MY_APP_TAG", "WebView crashed too many times. Showing error UI.")
showErrorUI()
}
}
private fun showErrorUI() {
// Example: Inflate an error view
}
override fun onDestroy() {
super.onDestroy()
myWebView?.let {
webViewContainer?.removeView(it)
it.destroy()
}
myWebView = null
}
}
Remarques importantes
Lorsque vous implémentez onRenderProcessGone, tenez compte des points suivants pour garantir la stabilité de l'application et maintenir la visibilité des événements d'arrêt :
- Plantages répétés : si un moteur de rendu plante lors du chargement d'une page spécifique, ne rechargez pas immédiatement la même page. Cela pourrait entraîner un nouveau plantage de WebView.
- Visibilité : les arrêts d'application causés par l'absence de ce rappel ne sont pas encore reflétés dans les rapports de plantage de la Play Console. Bien que les futures mises à jour puissent combler cette lacune, vous devez résoudre ces problèmes dès maintenant pour garantir la stabilité de l'application. L'implémentation de ce gestionnaire permet de voir immédiatement pourquoi votre application se ferme.