android - 监听来自 java 的 javascript 函数调用 - Android

标签 android webview

我在服务器上托管了一些 HTML5/javascript 文件。当在 HTML5 页面上单击按钮时,将调用 javascript 函数。我想监听函数何时被调用并获取函数返回的 json。以前我在设备上打开一个端口,但在 Android 3.0 上似乎不起作用。我听说您可以使用外部接口(interface) 来监听 javascript 调用,但我不知道如何实现。

最佳答案

要使用外部接口(interface),您需要在 WebView 中运行您的网站。此外,以下解决方案意味着什么

  1. 您知道要拦截的所有函数名称,并且...
  2. 这些函数在 JS 代码的公共(public)范围内。

要注册您的界面,您需要调用 addJavascriptInterface WebView 实例上的方法。您需要为其选择一个名称并创建一个实现。您的界面应该拦截函数调用并报告其结果,所以,让我们描述一下...

class FunctionCallInterceptor {
    public void reportCall(String functionName, String result) {
      // some code, handling interception
    }
}

然后注册...

mWebView.addJavascriptInterface(new FunctionCallInterceptor(), 'Interceptor');

有关 JavaScript 接口(interface)的更多信息,请参阅 Binding JavaScript

然后您需要将函数结果“传输”到您的界面...这里您需要一些 JavaScript 代码。

function wrapFunc(name) {
  if(typeof window[name] == 'function') {  // If target is accessible
    var original = window['__' + name] = window[name];  // remember original one
    window[name] = function() {  // and replace with wrapper
        var result = original.apply(this, arguments); // call original                
        Interceptor.reportCall(name, result.toString()); // report to interceptor
        return result;  // return result as usual
    }
  }
}

使用这段代码包装你的函数

wrapFunc('myFunction'); // wraps myFunction in the source

此外,不要忘记启用 JavaScript

mWebView.getSettings().setJavaScriptEnabled(true);

何时,如何将此代码嵌入到您的外部页面(我的意思是您无法访问外部 JS 代码)...要在页面上下文中执行任意代码,您可以使用 loadUrl WebView

方法
mWebView.loadUrl('javascript:some... js... code...');

这不会触发页面重新加载,只会执行 JavaScript。请注意在页面完全加载后需要执行此操作的内容。您可以通过以下代码获取:

mWebView.setWebViewClient(new WebViewClient {
    @Override
    public void onPageFinished (WebView view, String url) {
        // here page is loaded
    }
});

参见 setWebViewClientonPageFinished详情

另请注意,通过 loadUrl 调用传输到页面的代码不得包含换行符。所以你需要摆脱它们(通过 String.replace 左右)。

添加 所以,最终的解决方案是:

String wrapFuncCode = "function wrapFunc ...... "; // or maybe place it in resources?
mWebView.addJavascriptInterface(new FunctionCallInterceptor(), 'Interceptor');
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient {
    @Override
    public void onPageFinished (WebView view, String url) {
       // inject wrapper
       // don't forget to remove newline chars
       mWebView.loadUrl("javascript:" + wrapFuncCode.replace('\n', ''));

       // wrap all the functions needed
       String[] funcToWrap = new String[] { 'myFunc1', ... };
       for(String f : funcToWrap) {
           mWebView.loadUrl("javascript:wrapFunc('" + f + "myFunction');");  
       }  
    }
});

关于android - 监听来自 java 的 javascript 函数调用 - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9306801/

相关文章:

android - AsyncTask 和 Firebase

android - 使用软件渲染在嵌入式平台上移植 Android

android - 如何将我的 WebView 字体设置为设备的当前字体?

java - Android:在 ListView 行中填充多个项目

android - 搜索 View 关闭图标显示为禁用而不是白色

javascript - 如何访问 <webview> 的窗口对象

java - Android WebView 中的上传按钮不起作用

java - 停止记住表单数据

javascript - 停止在 Url 重定向 android 上加载网页

Javamail getContent() fatal error java.lang.NoClassDefFoundError