Android fournit un contrôle WebView très puissant pour le traitement des pages Web, et dans la page Web, JavaScript est un autre script très important. Cet article expliquera comment implémenter des appels mutuels entre le code Java et le code Javascript.
Il est très pratique de réaliser l'interaction entre Java et js. Habituellement, seules les étapes suivantes sont requises.
WebView permet l'exécution de scripts JavaScript
WebView définit une interface interactive pour les appels JavaScript.
Le client et la page Web écrivent du code pour s'appeler.
Pour faciliter l'explication, tout le code est publié en premier
Code Java
package com.example.javajsinteractiondemo; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.webkit.JavascriptInterface; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; public class MainActivity extends Activity { private static final String LOGTAG = "MainActivity"; @SuppressLint("JavascriptInterface") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final WebView myWebView = (WebView) findViewById(R.id.myWebView); WebSettings settings = myWebView.getSettings(); settings.setJavaScriptEnabled(true); myWebView.addJavascriptInterface(new JsInteration(), "control"); myWebView.setWebChromeClient(new WebChromeClient() {}); myWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); testMethod(myWebView); } }); myWebView.loadUrl("file:///android_asset/js_java_interaction.html"); } private void testMethod(WebView webView) { String call = "javascript:sayHello()"; call = "javascript:alertMessage(\"" + "content" + "\")"; call = "javascript:toastMessage(\"" + "content" + "\")"; call = "javascript:sumToJava(1,2)"; webView.loadUrl(call); } public class JsInteration { @JavascriptInterface public void toastMessage(String message) { Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); } @JavascriptInterface public void onSumResult(int result) { Log.i(LOGTAG, "onSumResult result=" + result); } } }
Code Web frontal
<html> <script type="text/javascript"> function sayHello() { alert("Hello") } function alertMessage(message) { alert(message) } function toastMessage(message) { window.control.toastMessage(message) } function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) } </script> Java-Javascript Interaction In Android </html>
Le format d'appel est window.jsInterfaceName.methodName(parameterValues) Dans cet exemple, nous utilisons le contrôle comme le nom de l’interface d’injection.
function toastMessage(message) { window.control.toastMessage(message) } function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }
Le format de base de webView appelant js est webView.loadUrl("javascript:methodName(parameterValues)")
String call = "javascript:sayHello()"; webView.loadUrl(call);
Notez que pour string comme valeur de paramètre, double les guillemets doivent être échappés.
String call = "javascript:alertMessage(\"" + "content" + "\")"; webView.loadUrl(call);
Android ne fournissait pas de méthode pour appeler directement les fonctions js et obtenir des valeurs avant la 4.4, donc avant cela, l'idée commune était Java appelle la méthode js une fois la méthode js exécutée, le code java est à nouveau appelé pour renvoyer la valeur.
1.Java appelle le code js
String call = "javascript:sumToJava(1,2)"; webView.loadUrl(call);
2.js traitement de la fonction et renvoie le résultat en appelant la méthode java
function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }
3.Java dans la méthode de rappel Get la fonction js renvoie la valeur dans
@JavascriptInterface public void onSumResult(int result) { Log.i(LOGTAG, "onSumResult result=" + result); }
Utilisez évaluerJavascript après Android 4.4. Voici un exemple interactif simple d'une méthode js avec une valeur de retour
function getGreetings() { return 1; }
code Java lors de l'appel de la méthode évaluerJavascript
private void testEvaluateJavascript(WebView webView) { webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { Log.i(LOGTAG, "onReceiveValue value=" + value); }}); }
résultat de sortie
I/MainActivity( 1432): onReceiveValue value=1
Remarque
Ce qui précède limite le résultat renvoyé à String Pour les types simples, il essaiera d'être converti en chaîne et renvoyé pour les types de données complexes. est recommandé de le renvoyer sous forme de chaîne. Le json est renvoyé. La méthode
evaluateJavascript doit être appelée dans le thread de l'interface utilisateur (thread principal), donc onReceiveValue est également exécuté dans le thread principal.
Vous n'auriez pas dû configurer WebChromeClient, suivez le code suivant pour le définir up
myWebView.setWebChromeClient(new WebChromeClient() {});
La raison du problème est que le code js de la page Web n'a pas été chargé , donc la méthode js est appelée. La solution est d'appeler la méthode js
myWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); //在这里执行你想调用的js函数 } });
Si le problème ne se produit que sur les machines équipées de la version 4.2 ou supérieure, le problème vient du fait que le système est soumis à des restrictions de sécurité. La documentation Android dit ceci
Attention : Si vous avez défini votre targetSdkVersion sur 17 ou supérieur, vous devez ajouter l'annotation @JavascriptInterface à toute méthode que vous souhaitez rendre disponible dans le code de votre page Web (la méthode doit également publique). Si vous ne fournissez pas l'annotation, la méthode ne sera pas accessible par votre page Web lors de l'exécution sur Android 4.2 ou supérieur.
La signification chinoise est
Attention : Si votre programme cible la plateforme 17 ou supérieure, vous devez ajouter l'annotation @JavascriptInterface à la méthode appelable par la page web (cette méthode doit être publique). Si vous ne le faites pas, la page Web ne pourra pas accéder à votre méthode sur les plateformes 4.2 et ultérieures.
Définissez targetSdkVersion sur 17 ou supérieur et introduisez l'annotation @JavascriptInterface
Créer une interface d'annotation nommé @JavascriptInterface vous-même, puis importez-le. Notez que cette interface ne peut pas être confondue.
Remarque, créez le code @JavascriptInterface
public @interface JavascriptInterface { }
S'il s'exécute normalement dans la version non obscurcie, il s'exécutera normalement dans la version obscurcie Le code ne s'exécute pas correctement et affiche Uncaught TypeError: Object [object Object] has no method, c'est-à-dire que vous n'avez pas effectué de gestion des exceptions obscurcies. Ajoutez un code comme celui-ci au fichier obscurci
-keep class com.example.javajsinteractiondemo$JsInteration { *; }
Les journaux de filtre ont découvert ce problème.
E/StrictMode( 1546): java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {528712d4} called on Looper (JavaBridge, tid 121) {52b6678c}, FYI main Looper is Looper (main, tid 1) {528712d4}) E/StrictMode( 1546): at android.webkit.WebView.checkThread(WebView.java:2063) E/StrictMode( 1546): at android.webkit.WebView.loadUrl(WebView.java:794) E/StrictMode( 1546): at com.xxx.xxxx.xxxx.xxxx.xxxxxxx$JavaScriptInterface.onCanGoBackResult(xxxx.java:96) E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method) E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27) E/StrictMode( 1546): at android.os.Handler.dispatchMessage(Handler.java:102) E/StrictMode( 1546): at android.os.Looper.loop(Looper.java:136) E/StrictMode( 1546): at android.os.HandlerThread.run(HandlerThread.java:61)
Le thread de rappel Java après l'appel js n'est pas le thread principal. Si vous imprimez le journal, vous pouvez vérifier
ThreadInfo=Thread[WebViewCoreThread,5,main]
Pour résoudre l'exception ci-dessus, placez simplement l'opération WebView dans le thread principal.
webView.post(new Runnable() { @Override public void run() { webView.loadUrl(YOUR_URL). } });
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!