Initialisation WebView¶
1. « JavaScript est activé. »¶
WebView a javaScriptEnabled = true (Android) ou équivalent, donc le code JS à l'intérieur de la page chargée peut réellement s'exécuter.
Sans cela, les balises <script> et toute logique JS dans votre HTML seraient complètement ignorées par WebView.
L'activation de JS est nécessaire pour :
- Appeler des fonctions de pont natif depuis JS.
- Gérer les événements de clic, les mises à jour dynamiques de l'IU, les appels AJAX/fetch, etc.
Point de sécurité :
- N'activez JS que pour les pages auxquelles vous faites confiance ou que vous contrôlez (ex. le propre HTML de votre application, pas des URLs non fiables arbitraires).
- Combinez cela avec d'autres restrictions (ex. chargement d'URL restreint, politiques de sécurité du contenu).
2. « Un WebViewClient/WebChromeClient sécurisé est attaché. »¶
WebViewClient :
- Contrôle la façon dont les URLs sont chargées (dans l'application vs le navigateur externe).
- Permet d'intercepter et de valider la navigation (ex. bloquer les domaines inconnus, les liens profonds).
- Idéal pour appliquer des règles comme « autoriser uniquement https://my-app-domain.com »
WebChromeClient :
- Gère les fonctionnalités avancées de type navigateur :
- Dialogues JavaScript (alert, confirm, prompt)
- Journaux de console
- Permissions (caméra, géolocalisation, etc.)
-
Vous donne des crochets pour approuver/refuser ce que JS essaie de faire.
-
« Sécurisé » signifie ici que vous n'utilisez pas simplement le comportement par défaut :
- Vous remplacez les méthodes pour :
- Valider les URLs cibles avant le chargement.
- Empêcher le contenu mixte ou le HTTP en clair si non nécessaire.
- Contrôler l'accès aux fichiers, à la caméra ou d'autres fonctionnalités sensibles.
Vous désactivez ou limitez les fonctionnalités dangereuses (ex. accès arbitraire aux fichiers, accès universel depuis les URLs de fichiers, etc.) sauf si explicitement requis.
3. « Tous les gestionnaires de pont sont enregistrés lors de l'initialisation. »¶
Votre pont natif expose des « gestionnaires » spécifiques (endpoints) que JS peut appeler, ex. :
- takePhoto
- getUserToken
- openSettings
« Enregistrés lors de l'initialisation » signifie :
- Dès que WebView (ou le module de pont) est créé, vous appelez quelque chose comme :
bridge.registerHandler("takePhoto", handlerFunction)
- Au moment où la page finit de charger, tous les gestionnaires attendus existent.
Pourquoi c'est important :
- Évite les conditions de course où JS appelle un gestionnaire qui n'est pas encore enregistré → erreurs comme « gestionnaire introuvable ».
- Fournit un contrat clair entre JS et le natif :
- L'ensemble des API disponibles est connu à l'avance.
- Vous pouvez les documenter et les versionner.
Avantage sécurité :
- Vous enregistrez uniquement ce que vous souhaitez exposer explicitement.
- Vous n'ouvrez pas accidentellement des méthodes natives aléatoires à JS.
- Vous pouvez ajouter des vérifications d'autorisation/permission à l'intérieur de chaque gestionnaire.
4. « JS peut appeler des méthodes natives en utilisant window.bridge.callHandler(...). »¶
C'est la surface API que JS voit pour communiquer avec le code natif. Forme d'appel typique :
window.bridge.callHandler("takePhoto", { quality: "high" }, function (response) { /* handle result */ });
En coulisses :
callHandlerregroupe le nom du gestionnaire + les données dans un message.- Envoie le message à travers le pont JS–natif (via addJavascriptInterface, postMessage, ou des schémas d'URL personnalisés, selon votre implémentation).
- Le code natif le reçoit, recherche le gestionnaire enregistré, l'exécute, puis envoie une réponse en retour, ce qui déclenche le rappel JS.
Avantages de conception :
- Point d'entrée unique de JS vers natif, au lieu d'exposer de nombreux globaux aléatoires.
- Facile à journaliser, auditer et valider :
- Vous pouvez journaliser chaque appel callHandler et ses arguments côté natif.
- Prend bien en charge les opérations asynchrones : le natif peut se terminer plus tard puis invoquer le rappel JS avec succès/erreur.
Enregistrement des Gestionnaires de Pont¶
Les gestionnaires sont enregistrés comme suit :
bridgeWebView.registerHandler("mqttConnect", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
// native code
}
});
Ce que fait cette ligne conceptuellement¶
-
Enregistre une API de pont nommée
"mqttConnect"est le nom du gestionnaire (le nom de l'API que JS appellera).- Vous indiquez au pont :
"Quand JS appelle mqttConnect, exécuter ce code Java."
-
Connecte le monde JS → la logique MQTT native :
- Ce gestionnaire est destiné à la logique de connexion MQTT (ex. connexion à un broker, authentification, etc.).
- Tout le travail lourd (sockets, identifiants, nouvelles tentatives, etc.) reste dans le code natif, pas dans JS.
Scan et Connexion à un Appareil BLE¶
Cet extrait montre comment le code JavaScript WebView communique avec la couche native (Android/iOS) via bridgeWebView pour :
- Enregistrer des rappels pour les événements BLE
- Démarrer le scan des appareils BLE
- Se connecter à un appareil en utilisant son adresse MAC
// Step 1: Register callbacks
bridgeWebView.registerHandler("findBleDeviceCallBack", function(data) {
const device = JSON.parse(data);
console.log("Found:", device.name, device.macAddress);
});
bridgeWebView.registerHandler("bleConnectSuccessCallBack", function(macAddress) {
console.log("Connected to:", macAddress);
});
// Step 2: Start scanning
bridgeWebView.callHandler("startBleScan", "", function(response) {
const result = JSON.parse(response);
if (result.success) {
console.log("Scanning started...");
}
});
// Step 3: Connect to device (when you find the one you want)
setTimeout(() => {
bridgeWebView.callHandler("connBleByMacAddress", "AA:BB:CC:DD:EE:FF", function(response) {
const result = JSON.parse(response);
if (result.success) {
console.log("Connecting...");
}
});
}, 5000);
Vue d'ensemble¶
bridgeWebViewest l'objet de pont JavaScript–natif exposé dans WebView.- registerHandler(name, callback) enregistre une fonction JavaScript que l'application native peut appeler.
- callHandler(name, data, callback) appelle une fonction native et reçoit optionnellement une réponse asynchrone.
Le flux général est :
- Le côté JS enregistre des gestionnaires pour que le code natif puisse notifier la page web.
- JS indique au code natif de commencer le scan des appareils BLE.
- Lorsqu'un appareil est trouvé, le natif rappelle JS.
- JS décide à quel appareil se connecter et appelle la fonction native « connect ».
Étape 1 : Enregistrement des Rappels du Natif vers JS¶
findBleDeviceCallBack
bridgeWebView.registerHandler("findBleDeviceCallBack", function(data) {
const device = JSON.parse(data);
console.log("Found:", device.name, device.macAddress);
});
- Objectif : Ce gestionnaire est déclenché par la couche native chaque fois qu'un appareil BLE est découvert lors d'un scan.
-
Paramètres :
data: une chaîne JSON envoyée depuis le code natif. Elle est censée représenter un objet appareil, par exemple :{ "name": "My BLE Device", "macAddress": "AA:BB:CC:DD:EE:FF" }
-
Logique :
-
JSON.parse(data) convertit la chaîne JSON en objet JavaScript.
- device.name et device.macAddress sont lus depuis l'objet analysé.
- Les informations sur l'appareil sont journalisées :
console.log("Found:", device.name, device.macAddress);
-
Comment l'utiliser :
- Vous pouvez ensuite remplacer le
console.logpar des mises à jour de l'IU, ex. ajouter l'appareil à une liste pour que l'utilisateur le sélectionne.
- Vous pouvez ensuite remplacer le
bleConnectSuccessCallBack
bridgeWebView.registerHandler("bleConnectSuccessCallBack", function(macAddress) {
console.log("Connected to:", macAddress);
});
- Objectif : Notifie le côté JS qu'une connexion BLE a été établie avec succès.
-
Paramètres :
macAddress: une chaîne simple contenant l'adresse MAC de l'appareil connecté.
-
Logique :
- Journalise l'adresse MAC de l'appareil connecté avec succès :
console.log("Connected to:", macAddress);
- Journalise l'adresse MAC de l'appareil connecté avec succès :
-
Comment l'utiliser :
- C'est un bon endroit pour mettre à jour l'IU vers l'état « Connecté » ou activer des fonctionnalités qui nécessitent une connexion BLE active.
Étape 2 : Démarrage du Scan BLE¶
bridgeWebView.callHandler("startBleScan", "", function(response) {
const result = JSON.parse(response);
if (result.success) {
console.log("Scanning started...");
}
});
- Objectif : Demande à la couche native de commencer le scan des appareils BLE.
-
Arguments :
- Premier argument : "startBleScan" — le nom de la méthode native.
- Deuxième argument : "" — une chaîne vide ; aucun paramètre supplémentaire n'est nécessaire pour cet appel.
- Troisième argument : fonction de rappel pour gérer la réponse native.
-
Gestion de la réponse :
- response est censée être une chaîne JSON, ex. :
{ "success": true }
- response est censée être une chaîne JSON, ex. :
-
Elle est analysée en objet JavaScript :
const result = JSON.parse(response); -
Si result.success est true, le scan a démarré avec succès :
if (result.success) { console.log("Scanning started..."); } -
Flux :
- Après le démarrage du scan, le côté natif commencera généralement à appeler findBleDeviceCallBack chaque fois qu'il découvrira des appareils.
Étape 3 : Connexion à un Appareil par Adresse MAC¶
setTimeout(() => {
bridgeWebView.callHandler("connBleByMacAddress", "AA:BB:CC:DD:EE:FF", function(response) {
const result = JSON.parse(response);
if (result.success) {
console.log("Connecting...");
}
});
}, 5000);
- Objectif : Se connecte à un appareil BLE spécifique en utilisant son adresse MAC.
-
setTimeout :
setTimeout(..., 5000);retarde cet appel de 5 secondes.- Cela simule : « attendre un certain temps pendant le scan et la découverte des appareils, puis essayer de se connecter ».
- Dans une vraie application, vous appelleriez probablement ceci après que l'utilisateur sélectionne un appareil dans une liste (au lieu d'utiliser un délai fixe).
Arguments de callHandler :
"connBleByMacAddress": la méthode native responsable de la connexion à un appareil."AA:BB:CC:DD:EE:FF": l'adresse MAC de l'appareil cible (espace réservé ; doit être remplacé par l'adresse MAC réelle de l'appareil provenant de findBleDeviceCallBack ou de la sélection de l'utilisateur).function(response) { ... }: rappel qui gère la réponse native.
Gestion de la réponse : - response est censée être une chaîne JSON, ex. :
{ "success": true }
-
Elle est analysée :
const result = JSON.parse(response); -
Si
result.successesttrue, il journalise :console.log("Connecting...");
Après l'établissement réel de la connexion, le côté natif doit déclencher le gestionnaire bleConnectSuccessCallBack enregistré à l'Étape 1.
Résumé du Flux de Bout en Bout¶
-
Enregistrer les rappels
findBleDeviceCallBack: appelé par le natif lorsqu'un appareil est trouvé.bleConnectSuccessCallBack: appelé par le natif lorsqu'une connexion réussit.
-
Démarrer le scan
- JS appelle startBleScan.
- Le natif commence le scan et retourne
{ success: true }si réussi. - Au fur et à mesure que les appareils sont trouvés, le natif appelle répétitivement
findBleDeviceCallBackavec les données de l'appareil.
-
Sélectionner et se connecter
- JS décide à quel appareil se connecter (dans l'exemple : une adresse MAC codée en dur après 5 secondes).
- JS appelle connBleByMacAddress avec l'adresse MAC choisie.
- Le natif tente une connexion et répond avec
{ success: true }si le processus de connexion démarre correctement. - Une fois entièrement connecté, le natif déclenche
bleConnectSuccessCallBackavec l'adresse MAC de l'appareil. Vous pouvez adapter les journaux aux mises à jour de l'IU (affichage des appareils dans une liste, affichage de l'état de connexion, etc.) et ajouter la gestion des erreurs en vérifiantresult.success === falseet en affichant des messages appropriés.