Взаимодействие WebView с JavaScript

WebView — это компонент, с помощью которого можно отображать веб-страницы. Однако нас интересует не только показ содержимого страницы, нам нужно также взаимодействовать с этим содержимым. В этой статье мы попытаемся объяснить некоторые детали этого процесса.

Важно! Прежде всего, если вы хотите загрузить веб-страницу из Интернета, не забудьте добавить следующее разрешение в файл AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET"/>

Есть несколько способов задать содержимое для WebView.

WebView webView = findViewById(R.id.WebView);
// Пример 1: задать URL адрес
webView.loadUrl("https://android-tools.ru");
// Пример 2: задать HTML-файл из папки raw
webView.loadUrl("file:///Android_res/raw/some_file.HTML");
// Пример 3: задать HTML-файл из папки assets
webView.loadUrl("file:///Android_asset/some_file.HTML");
// Пример 4: задать содержимое HTML в виде строки
String rawHTML = "<HTML>"+ "<body><h1>HTML content</h1></body>"+ "</HTML>";
webView.loadData(rawHTML, "text/HTML", "UTF-8");

Класс WebSettings

Этот класс позволяет управлять настройками состояния WebView. Когда WebView создаётся, он получает набор настроек по умолчанию. Эти настройки по умолчанию можно получить с помощью вызова геттера. Объект WebSettings, полученный из webView.getSettings(), привязан к времени существования этого объекта WebView. Если WebView был уничтожен, любой вызов метода WebSettings вызовет исключение IllegalStateException.

Чтобы использовать JavaScript, нужно включить его, вызвав у объекта WebSettings метод setJavaScriptEnabled().

WebView webView = findViewById(R.id.WebView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);

Класс WebViewClient

WebViewClient вызывается, когда выполняется рендеринг содержимого страницы. Вы также можете перехватит здесь загрузку URL (с помощью метода shouldOverrideUrlLoading()).

WebViewClient позволяет прослушивать события веб-страницы, например, когда она начинает загружаться, или завершила загрузку, когда произошла ошибка, связанная с загрузкой страницы, отправкой формы, ссылками, и другими событиями.

Реализация экземпляра WebViewClient может быть, например, следующей.

private class MyWebViewClient extends WebViewClient {
  @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return super.shouldOverrideUrlLoading(view, request);
  }

  @Override public void onPageFinished(WebView view, String url) {
  }

  @Override
  public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
    super.onReceivedError(view, request, error);
  }
}

Затем задать WebViewClient для WebView можно с помощью метода setWebViewClient().

webView.setWebViewClient(new MyWebViewClient());

Класс WebChromeClient

Этот класс позволяет прослушивать вызовы JavaScript, уведомления текущей страницы, такие как сообщения консоли, предупреждения, прогресс обновления страницы и другие вызовы JavaScript.

С помощью WebChromeClient мы можем обрабатывать события JS.

private class MyWebChromeClient extends WebChromeClient {
  @Override
  public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
    return true;
  }

  @Override
  public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
    return true;
  }

  @Override
  public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
      final JsPromptResult result) {
    return true;
  }
}

Затем задать экземпляр WebChromeClient можно следующим способом.

webView.setWebChromeClient(new MyWebChromeClient());

Привязка JavaScript к Android

WebView позволяет привязать код JavaScript к коду Android через интерфейс.

Для этого мы должны использовать метод addJavaScriptInterface(), в который передаются класс, предоставляющий интерфейс для JS, и имя, которое будет использоваться для отображения экземпляра в JS (например, «AndroidFunction«). В результате будет создан интерфейс с именем AndroidFuction для JavaScript, работающего в WebView.

С помощью этого способа мы можем:

  1. Выполнить метод, описанный в Java, из JS.
  2. Выполнить из Java метод, описанный в JS.

JavaScript вызывает Java

Например, опишем класс с нашими методами, которые мы хотим выполнить в JS.

public class JavaScriptInterface {
  Context mContext;

  JavaScriptInterface(Context c) {
    mContext = c;
  }

  @JavascriptInterface
  public void showToast(String toast) {
    Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
  }
}

Примечание: аннотация @JavascriptInterface обязательна для API 17 и выше.

Затем установим этот интерфейс в WebView.

webView.addJavascriptInterface(new JavaScriptInterface(this), "AndroidFunction");

Для взаимодействия с java-кодом в JS мы должны использовать имя интерфейса.

<!DOCTYPE >
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript">
           function init()
           {
              var testVal = 'Привет от Android Tools!';
              AndroidFunction.showToast(testVal);
           }
        </script>
  </head>
  <body>
    <div style="clear: both;height: 3px;"> </div>
    <div>
      <input value="submit" type="button" name="submit"
           id="btnSubmit" onclick="javascript:return init();" />
    </div>
  </body>
</html>

 

Java вызывает JavaScript

Допустим, у нас есть такой код на HTML.

<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <center><b><u>Javascript</u></b></center>
    <div id="msg">0</div>
    <script>
      function increment() {
      var ob = document.getElementById("msg");
      ob.innerText = parseInt(ob.innerText) + 1;
      }
    </script>
  </body>
</html>

Тогда в Java-коде нам нужно добавить вызов метода loadUrl(), в параметры которого нужно передать имя объявленного в JS метода.

webView.loadUrl("javascript:increment()");

После этого, загрузив страницу, мы можем выполнять код JavaScript прямо из Java.

Взаимодействие WebView с JavaScript: 7 комментариев

  1. Евгений

    Так а все таки если из Java надо запустить JS функцию это надо постоянно перезапускать вебвью через loadurl по сути?

  2. Евгений

    «После этого, загрузив страницу, мы можем выполнять код JavaScript прямо из Java.»

    так вот это вот как???

  3. Евгений

    а понял. вызов не очищает вебвью. только медленно оно ((

  4. Евгений

    Все получилось, спасибо! Долго не мог найти ответа

  5. Павел

    Вместо
    webView.loadUrl(«javascript:increment()»);
    правильнее использовать
    webView.evaluateJavascript(«javascript:increment()», nil);
    Второй параметр — результат выполнения скрипта. В данном случае он не нужен.

  6. Петр

    Здравствуйте.
    У меня есть страница file:///android_asset/offline.html. Это offline на ней есть кнопка обновить проверить интернет соединение. По нажатию на нeё выполняется функция в JS и вызывает JAVA далее идет обновление обратно на сайт https://test.php. Как это сделать у меня не работает.

    @JavascriptInterface
    public void showToast(String toast) {
    //ТУТ ПРОВЕРКА ИНТЕРНЕТА

    asw_view.loadUrl(«https://test.ru»); ВОЗВРАЩАЕМСЯ ОБРАТНО не работает
    }

    Нуждаюсь в совете?

Добавить комментарий для Евгений Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *