Чтобы использовать внешние интерфейсы, вам нужно запустить свой сайт в WebView. Также следующее решение подразумевает, что
- вы знаете все имена функций, которые вы хотите перехватить, и ...
- эти функции находятся в публичной области кода JS.
Чтобы зарегистрировать свой интерфейс, вам необходимо вызвать метод addJavascriptInterface в вашем экземпляре WebView
. Вам нужно выбрать имя для него и создать реализацию. Ваш интерфейс должен перехватывать вызовы функций и сообщать об их результатах, поэтому давайте опишем это ...
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
Кроме того, не забудьте включить 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
}
});
Подробнее см. setWebViewClient и onPageFinished
Также обратите внимание, что код, передаваемый на страницу с помощью loadUrl
вызова, не должен содержать разрывов строк. Поэтому вам нужно избавиться от них (с помощью String.replace или около того).
ADD
Итак, окончательное решение:
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');");
}
}
});