Maison > interface Web > js tutoriel > Explication détaillée de l'interaction Java et JavaScript dans Android

Explication détaillée de l'interaction Java et JavaScript dans Android

黄舟
Libérer: 2017-03-15 17:30:58
original
1691 Les gens l'ont consulté

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.

Comment réaliser

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.

Cet exemple de code

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);
      }
  }

}
Copier après la connexion

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>
Copier après la connexion

Exemple d'appel

js appelle Java

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)
}
Copier après la connexion

Java appelle JS

Le format de base de webView appelant js est webView.loadUrl("javascript:methodName(parameterValues)")

Appel de js sans paramètres et aucune valeur de retourFonction

String call = "javascript:sayHello()";
webView.loadUrl(call);
Copier après la connexion

Appelez la fonction js avec des paramètres et aucune valeur de retour

Notez que pour string comme valeur de paramètre, double les guillemets doivent être échappés.

String call = "javascript:alertMessage(\"" + "content" + "\")";
webView.loadUrl(call);
Copier après la connexion

Appel de fonctions js avec des paramètres et des valeurs de retour

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);
Copier après la connexion

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)
}
Copier après la connexion

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);
}
Copier après la connexion

Traitement 4.4

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;
}
Copier après la connexion

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);
  }});
}
Copier après la connexion

résultat de sortie

I/MainActivity( 1432): onReceiveValue value=1
Copier après la connexion

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.

Q&A

L'alerte ne peut pas apparaître

Vous n'auriez pas dû configurer WebChromeClient, suivez le code suivant pour le définir up

myWebView.setWebChromeClient(new WebChromeClient() {});
Copier après la connexion

Uncaught ReferenceError : functionName n'est pas défini

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函数
  }

});
Copier après la connexion

Uncaught TypeError : Object [object Object] n'a pas de méthode

Problèmes de restriction de sécurité

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.

Deux solutions
  • 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 {

}
Copier après la connexion

Problème d'obscurcissement du code

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 {
    *;
}
Copier après la connexion

Toutes les méthodes WebView doivent être appelées sur le même fil

Les journaux de filtre ont découvert ce problème.

E/StrictMode( 1546): java.lang.Throwable: A WebView method was called on thread &#39;JavaBridge&#39;. 
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)
Copier après la connexion

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]
Copier après la connexion

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).
    }
});
Copier après la connexion


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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal