Слушайте вызов функции JavaScript из Java - Android - PullRequest
3 голосов
/ 16 февраля 2012

У меня есть несколько файлов HTML5 / javascript, размещенных на сервере.При нажатии кнопки на странице HTML5 вызывается функция javascript.Я хочу слушать, когда вызывается функция, и получать json, который функция возвращает.Ранее я открывал порт на устройстве, но он не работает на Android 3.0.Я слышал, что вы можете использовать внешний интерфейс для прослушивания вызовов javascript, но я не знаю, как это реализовать.

Ответы [ 2 ]

3 голосов
/ 16 февраля 2012

Чтобы использовать внешние интерфейсы, вам нужно запустить свой сайт в WebView. Также следующее решение подразумевает, что

  1. вы знаете все имена функций, которые вы хотите перехватить, и ...
  2. эти функции находятся в публичной области кода 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');");  
       }  
    }
});
2 голосов
/ 21 февраля 2012

Я сделал по-другому, и это сработало легко. Я использовал window.external.notify (String message). В моем java я использовал webview.addJavascriptInterface (new JSInterface (), "external"); и в моем классе JSInterface я сделал функцию public void notify (String messg) .messg содержит мой ответ от javascript.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...