Utilisez WebView pour diffuser une application Web ou une page Web dans une application cliente. La classe WebView est une extension de la classe View d'Android qui vous permet d'afficher des pages Web dans la mise en page de votre activité. Il n'inclut pas les fonctionnalités d'un navigateur Web entièrement développé, telles que les commandes de navigation ou une barre d'adresse. Par défaut, WebView ne fait qu'afficher une page Web.
WebView peut vous aider à fournir des informations dans votre application que vous devrez peut-être mettre à jour, comme un contrat d'utilisation ou un guide de l'utilisateur. Dans votre application Android, vous pouvez créer une Activity contenant un WebView, puis l'utiliser pour afficher votre document hébergé en ligne.
WebView peut également être utile lorsque votre application fournit à l'utilisateur des données qui nécessitent une connexion Internet pour être récupérées, comme les e-mails. Dans ce cas, il peut être plus facile de créer un WebView dans votre application Android qui affiche une page Web avec toutes les données utilisateur, plutôt que d'effectuer une requête réseau, puis d'analyser les données et de les afficher dans une mise en page Android. Vous pouvez plutôt concevoir une page Web adaptée aux appareils Android, puis implémenter un WebView dans votre application Android qui charge la page Web.
Ce document explique comment faire vos premiers pas avec WebView, comment lier le code JavaScript de votre page Web au code côté client de votre application Android, comment gérer la navigation sur les pages et comment gérer les fenêtres lorsque vous utilisez WebView.
Utiliser WebView sur les versions antérieures d'Android
Pour utiliser en toute sécurité les fonctionnalités WebView plus récentes sur l'appareil sur lequel votre application s'exécute, ajoutez la bibliothèque Jetpack Webkit. Il s'agit d'une bibliothèque statique que vous pouvez ajouter à votre application pour utiliser les API android.webkit qui ne sont pas disponibles pour les versions antérieures de la plate-forme.
Ajoutez-le à votre fichier build.gradle comme suit :
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
Groovy
dependencies { implementation ("androidx.webkit:webkit:1.8.0") }
Pour en savoir plus, consultez l'exemple WebView sur GitHub.
Ajouter une WebView à votre application
Pour ajouter un WebView à votre application, vous pouvez inclure l'élément <WebView> dans la mise en page de votre activité ou définir l'intégralité de la fenêtre Activity en tant que WebView dans onCreate.
Ajouter une WebView dans la mise en page de l'activité
Pour ajouter un WebView à votre application dans la mise en page, ajoutez le code suivant au fichier XML de mise en page de votre activité :
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
Pour charger une page Web dans WebView, utilisez loadUrl, comme illustré dans l'exemple suivant :
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.loadUrl("http://www.example.com")
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.loadUrl("http://www.example.com");
Ajouter une WebView dans onCreate()
Pour ajouter un WebView à votre application dans la méthode onCreate() d'une activité, utilisez une logique semblable à celle-ci :
Kotlin
val myWebView = WebView(activityContext) setContentView(myWebView)
Java
WebView myWebView = new WebView(activityContext); setContentView(myWebView);
Ensuite, chargez la page :
Kotlin
myWebView.loadUrl("http://www.example.com")
Java
myWebView.loadUrl("https://www.example.com");
Vous pouvez également charger l'URL à partir d'une chaîne HTML :
Kotlin
// Create an unencoded HTML string, then convert the unencoded HTML string into // bytes. Encode it with base64 and load the data. val unencodedHtml = "<html><body>'%23' is the percent code for ‘#‘ </body></html>"; val encodedHtml = Base64.encodeToString(unencodedHtml.toByteArray(), Base64.NO_PADDING) myWebView.loadData(encodedHtml, "text/html", "base64")
Java
// Create an unencoded HTML string, then convert the unencoded HTML string into // bytes. Encode it with base64 and load the data. String unencodedHtml = "<html><body>'%23' is the percent code for ‘#‘ </body></html>"; String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING); myWebView.loadData(encodedHtml, "text/html", "base64");
Votre application doit avoir accès à Internet. Pour obtenir l'accès à Internet, demandez l'autorisation INTERNET dans votre fichier manifeste, comme illustré dans l'exemple suivant :
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
Vous pouvez personnaliser votre WebView de l'une des manières suivantes :
- Activation de la compatibilité avec le plein écran à l'aide de
WebChromeClient. Cette classe est également appelée lorsqu'unWebViewdoit être autorisé à modifier l'UI de l'application hôte, par exemple pour créer ou fermer des fenêtres, ou envoyer des boîtes de dialogue JavaScript à l'utilisateur. Pour en savoir plus sur le débogage dans ce contexte, consultez Déboguer des applications Web. - Gérer les événements qui ont un impact sur l'affichage du contenu, tels que les erreurs lors de l'envoi de formulaires ou la navigation à l'aide de
WebViewClient. Vous pouvez également utiliser cette sous-classe pour intercepter le chargement d'URL. - Activer JavaScript en modifiant
WebSettings. - Utiliser JavaScript pour accéder aux objets du framework Android que vous avez injectés dans un
WebView.
Utiliser JavaScript dans WebView
Si la page Web que vous souhaitez charger dans votre WebView utilise JavaScript, vous devez activer JavaScript pour votre WebView. Une fois JavaScript activé, vous pouvez créer des interfaces entre le code de votre application et votre code JavaScript.
Activer JavaScript
JavaScript est désactivé par défaut dans un WebView. Vous pouvez l'activer via le WebSettings associé à votre WebView. Récupérez WebSettings avec getSettings, puis activez JavaScript avec setJavaScriptEnabled.
Consultez l'exemple suivant :
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.settings.javaScriptEnabled = true
Java
WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);
WebSettings permet d'accéder à divers autres paramètres qui pourraient vous être utiles. Par exemple, si vous développez une application Web conçue spécifiquement pour l'élément WebView de votre application Android, vous pouvez définir une chaîne user-agent personnalisée avec setUserAgentString, puis interroger le user-agent personnalisé sur votre page Web pour vérifier que le client qui demande votre page Web est bien votre application Android.
Lier du code JavaScript à du code Android
Lorsque vous développez une application Web conçue spécifiquement pour l'élément WebView de votre application Android, vous pouvez créer des interfaces entre votre code JavaScript et le code Android côté client. Par exemple, votre code JavaScript peut appeler une méthode dans votre code Android pour afficher un Dialog, au lieu d'utiliser la fonction alert() de JavaScript.
Pour lier une nouvelle interface entre votre code JavaScript et votre code Android, appelez addJavascriptInterface en lui transmettant une instance de classe à lier à votre code JavaScript et un nom d'interface que votre code JavaScript peut appeler pour accéder à la classe.
Pour en savoir plus sur la communication entre JavaScript et le code natif, y compris sur les API plus modernes et sécurisées, consultez Accéder aux API natives avec JSBridge.
Par exemple, vous pouvez inclure la classe suivante dans votre application Android :
Kotlin
/** Instantiate the interface and set the context. */ class WebAppInterface(private val mContext: Context) { /** Show a toast from the web page. */ @JavascriptInterface fun showToast(toast: String) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show() } }
Java
public class WebAppInterface { Context mContext; /** Instantiate the interface and set the context. */ WebAppInterface(Context c) { mContext = c; } /** Show a toast from the web page. */ @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } }
Dans cet exemple, la classe WebAppInterface permet à la page Web de créer un message Toast à l'aide de la méthode showToast().
Vous pouvez lier cette classe au code JavaScript qui s'exécute dans votre WebView avec addJavascriptInterface(), comme illustré dans l'exemple suivant :
Kotlin
val webView: WebView = findViewById(R.id.webview) webView.addJavascriptInterface(WebAppInterface(this), "Android")
Java
WebView webView = (WebView) findViewById(R.id.webview); webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Cela crée une interface appelée Android pour le code JavaScript exécuté dans WebView. À ce stade, votre application Web a accès à la classe WebAppInterface. Par exemple, voici du code HTML et JavaScript qui crée un message toast à l'aide de la nouvelle interface lorsque l'utilisateur appuie sur un bouton :
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>
Il n'est pas nécessaire d'initialiser l'interface Android à partir de JavaScript. Le WebView le rend automatiquement disponible sur votre page Web. Ainsi, lorsqu'un utilisateur appuie sur le bouton, la fonction showAndroidToast() utilise l'interface Android pour appeler la méthode WebAppInterface.showToast().
Gérer la navigation sur les pages
Lorsque l'utilisateur appuie sur un lien d'une page Web dans votre WebView, Android lance par défaut une application qui gère les URL. En général, le navigateur Web par défaut s'ouvre et charge l'URL de destination. Toutefois, vous pouvez modifier ce comportement pour votre WebView afin que les liens s'ouvrent dans votre WebView. Vous pouvez ensuite permettre à l'utilisateur de naviguer en avant et en arrière dans l'historique des pages Web géré par votre WebView.
Pour ouvrir les liens sur lesquels l'utilisateur appuie, fournissez un WebViewClient pour votre WebView à l'aide de setWebViewClient. Tous les liens sur lesquels l'utilisateur appuie se chargent dans votre WebView. Si vous souhaitez mieux contrôler l'emplacement de chargement d'un lien cliqué, créez votre propre WebViewClient qui remplace la méthode shouldOverrideUrlLoading. L'exemple suivant suppose que MyWebViewClient est une classe interne de Activity.
Kotlin
private class MyWebViewClient : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { if (Uri.parse(url).host == "www.example.com") { // This is your website, so don't override. Let your WebView load // the page. return false } // Otherwise, the link isn't for a page on your site, so launch another // Activity that handles URLs. Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { startActivity(this) } return true } }
Java
private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { if ("www.example.com".equals(request.getUrl().getHost())) { // This is your website, so don't override. Let your WebView load the // page. return false; } // Otherwise, the link isn't for a page on your site, so launch another // Activity that handles URLs. Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); startActivity(intent); return true; } }
Créez ensuite une instance de ce nouveau WebViewClient pour le WebView :
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.webViewClient = MyWebViewClient()
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
Désormais, lorsque l'utilisateur appuie sur un lien, le système appelle la méthode shouldOverrideUrlLoading, qui vérifie si l'hôte de l'URL correspond à un domaine spécifique, comme défini dans l'exemple précédent. Si c'est le cas, la méthode renvoie "false" et ne remplace pas le chargement de l'URL. Il permet à WebView de charger l'URL comme d'habitude.
Si l'hôte de l'URL ne correspond pas, un Intent est créé pour lancer l'Activity par défaut pour la gestion des URL, qui correspond au navigateur Web par défaut de l'utilisateur.
Gérer les URL personnalisées
WebView applique des restrictions lors de la demande de ressources et de la résolution de liens qui utilisent un schéma d'URL personnalisé. Par exemple, si vous implémentez des rappels tels que shouldOverrideUrlLoading ou shouldInterceptRequest, WebView ne les appelle que pour les URL valides.
Par exemple, WebView peut ne pas appeler votre méthode shouldOverrideUrlLoading pour des liens comme celui-ci :
<a href="showProfile">Show Profile</a>
Les URL non valides, comme celle de l'exemple précédent, sont gérées de manière incohérente dans WebView. Nous vous recommandons donc d'utiliser une URL bien formée.
Vous pouvez utiliser un schéma personnalisé ou une URL HTTPS pour un domaine contrôlé par votre organisation.
Au lieu d'utiliser une chaîne simple dans un lien, comme dans l'exemple précédent, vous pouvez utiliser un schéma personnalisé comme celui-ci :
<a href="example-app:showProfile">Show Profile</a>
Vous pouvez ensuite gérer cette URL dans votre méthode shouldOverrideUrlLoading comme suit :
Kotlin
// The URL scheme must be non-hierarchical, meaning no trailing slashes. const val APP_SCHEME = "example-app:" override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return if (url?.startsWith(APP_SCHEME) == true) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length), "UTF-8") respondToData(urlData) true } else { false } }
Java
// The URL scheme must be non-hierarchical, meaning no trailing slashes. private static final String APP_SCHEME = "example-app:"; @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith(APP_SCHEME)) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length()), "UTF-8"); respondToData(urlData); return true; } return false; }
L'API shouldOverrideUrlLoading est principalement destinée à lancer des intents pour des URL spécifiques. Lorsque vous l'implémentez, veillez à renvoyer false pour les URL gérées par WebView. Toutefois, vous n'êtes pas limité au lancement d'intents. Vous pouvez remplacer le lancement d'intents par n'importe quel comportement personnalisé dans les exemples de code précédents.
Parcourir l'historique des pages Web
Lorsque votre WebView remplace le chargement d'URL, il accumule automatiquement un historique des pages Web visitées. Vous pouvez parcourir l'historique en arrière et en avant avec goBack et goForward.
Par exemple, l'exemple suivant montre comment votre Activity peut utiliser le bouton Retour de l'appareil pour revenir en arrière :
Kotlin
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { // Check whether the key event is the Back button and if there's history. if (keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack()) { myWebView.goBack() return true } // If it isn't the Back button or there isn't web page history, bubble up to // the default system behavior. Probably exit the activity. return super.onKeyDown(keyCode, event) }
Java
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { // Check whether the key event is the Back button and if there's history. if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) { myWebView.goBack(); return true; } // If it isn't the Back button or there's no web page history, bubble up to // the default system behavior. Probably exit the activity. return super.onKeyDown(keyCode, event); }
Si votre application utilise Jetpack AppCompat 1.6.0 ou une version ultérieure, vous pouvez simplifier encore davantage l'extrait de code précédent :
Kotlin
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack() } }
Java
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack(); } }
La méthode canGoBack renvoie "true" s'il existe un historique des pages Web que l'utilisateur peut consulter. De même, vous pouvez utiliser canGoForward pour vérifier s'il existe un historique de navigation vers l'avant. Si vous n'effectuez pas cette vérification, goBack et goForward ne font rien une fois que l'utilisateur a atteint la fin de l'historique.
Pour conserver l'historique de navigation lors de la recréation d'une activité ou de la récupération d'un processus en arrière-plan, utilisez saveState pour sérialiser l'historique de navigation de la WebView dans un Bundle, et restoreState pour le restaurer.
Pour savoir comment gérer de manière sécurisée les limites de taille de l'état enregistré et éviter les TransactionTooLargeException, consultez Gérer efficacement l'état de WebView.
Gérer les modifications de configuration de l'appareil
Pendant l'exécution, l'état de l'activité change lorsque la configuration d'un appareil est modifiée, par exemple lorsque les utilisateurs font pivoter l'appareil ou ferment un éditeur de mode de saisie (IME). Ces modifications entraînent la destruction de l'activité d'un objet WebView et la création d'une nouvelle activité, qui crée également un objet WebView chargeant l'URL de l'objet détruit. Vous pouvez utiliser saveState dans onSaveInstanceState() et restoreState lors de la recréation pour restaurer le contexte de navigation de l'utilisateur. Pour découvrir des stratégies permettant de gérer la taille de l'état de manière sécurisée, consultez Gérer efficacement l'état de WebView.
Pour modifier le comportement par défaut de votre activité, vous pouvez modifier la façon dont elle gère les modifications de orientation dans votre fichier manifeste. Pour en savoir plus sur la gestion des modifications de configuration pendant l'exécution, consultez Gérer les modifications de configuration.
Gérer les fenêtres
Par défaut, les demandes d'ouverture de nouvelles fenêtres sont ignorées. Cela est vrai, qu'elles soient ouvertes par JavaScript ou par l'attribut cible dans un lien. Vous pouvez personnaliser votre WebChromeClient pour définir votre propre comportement d'ouverture de plusieurs fenêtres.
Pour renforcer la sécurité de votre application, il est préférable d'empêcher l'ouverture de pop-ups et de nouvelles fenêtres. Le moyen le plus sûr d'implémenter ce comportement consiste à transmettre "true" à setSupportMultipleWindows, mais pas à remplacer la méthode onCreateWindow, dont dépend setSupportMultipleWindows().
Cette logique empêche le chargement de toute page utilisant target="_blank" dans ses liens.
Gérer la mémoire et les performances
Étant donné que WebView s'exécute sur un moteur basé sur Chromium avec des processus distincts et du code natif, son utilisation de mémoire de référence est plus élevée que celle des vues Android standards.
La réutilisation des instances WebView et leur destruction correcte sont essentielles pour maintenir une application stable.
Pour en savoir plus sur le diagnostic et l'optimisation de l'espace mémoire utilisé par votre application lorsque vous utilisez du contenu Web, consultez Gérer et diagnostiquer la mémoire WebView.