我在服务器上托管了一些HTML5/javascript文件。当HTML5页面上的按钮被点击时,会调用一个javascript函数。我想监听函数被调用的时机,并获取函数返回的json数据。以前我是在设备上打开端口,但这在Android 3.0上似乎不起作用。我听说可以使用外部接口来监听javascript调用,但我不知道如何实现。
WebView
实例上调用addJavascriptInterface方法。您需要为其选择一个名称并创建一个实现。您的接口应该拦截函数调用并报告它们的结果,因此,让我们对其进行描述…class FunctionCallInterceptor {
public void reportCall(String functionName, String result) {
// some code, handling interception
}
}
并注册它...
mWebView.addJavascriptInterface(new FunctionCallInterceptor(), 'Interceptor');
更多关于JavaScript接口的信息,请参阅绑定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
mWebView.getSettings().setJavaScriptEnabled(true);
在没有访问外部JS代码的情况下,何时以及如何将此代码嵌入到您的外部页面中...要在页面上下文中执行任意代码,您可以使用WebView
的loadUrl方法。
mWebView.loadUrl('javascript:some... js... code...');
这不会触发页面重新加载,只有JavaScript将被执行。请注意,在页面完全加载后执行此操作所需的内容。您可以通过以下代码获取此内容:
mWebView.setWebViewClient(new WebViewClient {
@Override
public void onPageFinished (WebView view, String url) {
// here page is loaded
}
});
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');");
}
}
});
我采用了不同的方法,很容易就成功了。我使用了window.external.notify(String message)。在我的Java代码中,我使用了webview.addJavascriptInterface(new JSInterface(),"external"),并且在我的JSInterface类中,我编写了一个公共函数public void notify(String messg),messg包含了来自JavaScript的响应。