要使用外部接口,您需要在 WebView 中运行您的网站。以下解决方案也意味着,
- 您知道所有要拦截的函数名称,并且...
- 这些函数在 JS 代码的公共范围内。
要注册您的接口,您需要在您的WebView 实例上调用addJavascriptInterface 方法。您需要为其选择一个名称并创建一个实现。你的接口应该拦截函数调用并报告它们的结果,所以,让我们描述一下......
class FunctionCallInterceptor {
public void reportCall(String functionName, String result) {
// some code, handling interception
}
}
并注册它...
mWebView.addJavascriptInterface(new FunctionCallInterceptor(), 'Interceptor');
有关 JavaScript 接口的更多信息,请参阅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 代码)...要在页面上下文中执行任意代码,您可以使用 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
}
});
详情请参阅setWebViewClient 和onPageFinished
另请注意,通过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');");
}
}
});