首页 > 解决方案 > android无法从Javascript运行Java函数

问题描述

在我的项目中,我有一个WebView加载页面(HTML)。我想更改所有图像并在用户单击任何图像时显示敬酒。

所以我添加了调用 Java 函数的 javascript 代码:

// code is inside onPageFinished(..) function
JavaScriptInterface jsInterface = new JavaScriptInterface(activity);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(jsInterface, "JSInterface");

webView.evaluateJavascript(
  "var imgs = document.getElementsByTagName('img');" +
  "for (var i = 0; i < imgs.length; i++) {" +
  "imgs[i].src = 'file:///android_asset/rules_images_placeholder.png';" +
  "imgs[i].addEventListener('click', function() {" +
  "window.JSInterface.showToast(); " + // <-- isn't called: see logs
  "});" +
  "} " +
  "window.JSInterface.showToast();" // <-- is called
  , null);

JavaScript接口类:

public class JavaScriptInterface {
  private Activity activity;
  public JavaScriptInterface(Activity activity) {
    this.activity = activity;
  }
  @JavascriptInterface
  public void showToast() {
    Toast.makeText(activity, "Toast message", Toast.LENGTH_SHORT).show();
  }
}

showToast()应该在什么时候调用

  1. 页面已完成加载

  2. 用户点击了图片

问题:showToast()只调用一次 - 当页面完成加载时。当用户单击图像时,showToast()不会调用,而是出现以下日志:

未捕获的类型错误:无法读取未定义的属性“showToast”,来源:

问题

如何调用showToast()图片点击?

标签: javascriptandroid

解决方案


我不知道为什么,但您可以通过在加载 HTML 内容之前添加 JavaScript 界面来解决此问题。

jsInterface = new JavaScriptInterface(activity);
fragmentWebView.getSettings().setJavaScriptEnabled(true);
fragmentWebView.getSettings().setDomStorageEnabled(true);
fragmentWebView.addJavascriptInterface(jsInterface, "JSInterface");

fragmentWebView.loadDataWithBaseURL("file:///android_asset/", fullHtml, "text/html", "utf-8", null);
fragmentWebView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        view.loadUrl(
            "javascript:var imgs = document.getElementsByTagName('img');" +
            "for (var i = 0; i < imgs.length; i++) {" +
            "imgs[i].src = 'file:///android_asset/rules_images_placeholder.png';" +
            "imgs[i].addEventListener('click', function(e) {" +
            "window.JSInterface.showToast(); " +
            "});" +
            "}" +
            "console.log(window.JSInterface);" +
            "window.JSInterface.showToast(); ");
    }
});

推荐阅读