Взаимодействие 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.

Читайте также

Добавить комментарий

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