Начиная с 5 версии Android компонент WebView поставляется не как часть системы, а как обычное приложение которое может быть обновлено из Google Play:

image

Что это даёт разработчикам? Теперь HTML-приложения можно встраивать в .apk без дополнительных костылей. Все возможности HTML5 будут доступны.

Рассмотрим пример публикации в Google Play реального HTML5 приложения.

Готовое приложение можно скачать в Google Play, все исходные файлы (JS/HTML, ресурсы, код Java-оболочки) доступны в справке там же.

Шаг 1. Создание приложения HTML5 и настройка окружения


Этот шаг пропустим.

Если у вас нет готового приложения в HTML5 то и публиковать в Google Play пока нечего.
Последнюю Android Studio можно самостоятельно скачать тут.
Регистрация аккаунта в Google Play Console также выходит за рамки примера.

Шаг 2. Создание приложение Android


Открываем Студию, создаём новый проект и в минимальный API Level указываем как 21 (т.е. Android 5.0). Студия подсказывает что на данный момент это охватывает более двух третей устройств:

image

в ближайшие пару лет более старые устройства канут в Лету, но пока так.

В приложении нам нужна только одна (одно?) Activity содержащее WebView. Весь код буквально убирается на одной странице:

image

если интересно, его можно посмотреть по ссылке в приложении.

Всё что нам нужно это при старте в onCreate сделать пару настроек и открыть файл HTML-страницей. Примерно так

WebView webView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webView.loadUrl("file:///android_asset/index.html");

Шаг 3. Добавление файлов HTML


Добавляем в проект папку Asset:

image

и вываливаем туда наши файлы. Это всё.

Шаг 4. Интеграция с Android


В приложении есть внешние ссылки (например на исходники в GitHub или на создание сообщения в Twitter). Для этого сделаем свою реализацию shouldOverrideUrlLoading, примерно так:


@Override
boolean shouldOverrideUrlLoading(String url) {
		String host = Uri.parse(url).getHost();
		if (host.trim().length() > 0) {
			Uri webpage = Uri.parse(url);
			Intent myIntent = new Intent(Intent.ACTION_VIEW, webpage);
			startActivity(myIntent);
			return true;
		} else {
			return false;
		}
	}

— всего несколько строк, из них видно, что в случае ссылки на локальную страницу (в host пустая строка) оно не перехватывается и открывается в нашем WebView.

Если это внешняя страница то ссылка передаётся системе и она сама решит, нужно ли открыть её в Twitter, в выбранном пользователем браузере или ещё как-то.

Иногда нужно сделать наоборот и указать системе перехватывать некоторые ссылки и открывать их в нашем приложении. Для этого добавим в манифесте для нашего Activity дополнительный фильтр:

<intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    android:scheme="https"
                    android:host="surikov.github.io"
                    android:pathPrefix="/RiffShareAndroid/app/src/main/assets/load.html"/>
            </intent-filter>

— теперь любые ссылки в почте или веб-страницах будут проверяться на соответствие нашему сервису. Если это ссылка на наш сервис то будет предложено его открыть в нашем приложении:

image

Итого


Файл инсталляции занимает меньше 4Мб, есть полная интеграция с платформой Android, доступны все средства HTML5 (в данном примере это Web Audio).

В ближайшие пару лет доля старых устройств снизится до нуля и от Cordova можно будет полностью отказаться.

Комментарии (28)


  1. vintage
    15.09.2017 13:01
    +1

    А зачем делать это вручную да ещё и под каждую платформу, если это уже сделано в собственно кордове?


  1. MonkAlex
    15.09.2017 13:09
    -7

    Да здравствует ад ненативных и тормозящих приложений — теперь и на телефонах!


  1. RouR
    15.09.2017 13:32
    +2

    Работа с камерой? Покупки inapp?


  1. Focushift
    15.09.2017 13:39
    +2

    Как тогда без лишних телодвижений прикрутить SplashScreen?
    Открыть галерею?
    Вывести системный toast?
    Получить информацию о сетевом подключении?
    И т.д.


    1. musicriffstudio Автор
      15.09.2017 14:00

      это же полноценное андроидное приложение. Там можно всё то же что и в любом другом андроидном приложении.


      1. virpool
        15.09.2017 14:10
        +1

        В таком случае в статье явно не хватает упоминания о developer.android.com/guide/webapps/webview.html#BindingJavaScript


        1. Focushift
          15.09.2017 14:26
          +1

          Т.е. сделать аналог плагинов для кордовы?


        1. musicriffstudio Автор
          15.09.2017 14:28

          Во многих приложениях это просто не нужно.

          Смысл-то какой встраивать веб-приложения в андроидные .apk?

          У вас есть что-то готовое на HTML5 и прекрасно работающее само по себе (как в примере — импорт и экспорт из .mid, хороший звук, больше десятка живых инструментов, быстрая графика, адаптация под маленький экран и тач) и вам нужно малой кровью положить это в ГуглПлей со всей его инфраструктурой для распространения и монетизации.

          В этом случае всё оправданно.

          А если переделывать доступ к камере с хтмльного на андроидный то проще сразу под андроид и делать, без всякого HTML5.


          1. koeshiro
            16.09.2017 13:00

            А бывают случае когда нужно получить доступ к возможностям системы. Даже указанный вами пример может разрастись на столько что уже необходимо будет получить доступ… Скажем к камере


            1. musicriffstudio Автор
              16.09.2017 15:32

              доступ к камере и у любого современного браузера есть. А значит и у WebView начиная с Андроид 5.


              1. koeshiro
                16.09.2017 15:35

                Хорошо. Плохой пример. Вот реальный пример: Плагины. Можно писать всё самому с WebView, можно с cordova.org взять готовые, возможно подправить, накидать, и не парится. Грубо говоря — правильная лень. Иногда лучше взять готовое.


                1. musicriffstudio Автор
                  16.09.2017 16:05

                  нужно написать плагин в котором можно писать плагины пока ты пишешь плагины.

                  Плагины в Кордове это то что было необходимо пока ВебВью имел ограниченную функциональность. С пятого Андроида вместо ВебВью есть полноценный браузер который поддерживает всё что есть в хтмл5. А там много чего.


                  1. koeshiro
                    16.09.2017 16:39

                    Согласен. Но тут стоит добавить то что всё это придётся писать самому. Тоже самое что в веб для каждого проекта писать с нуля jq. Просто проще пользоваться готовым. Да, это может быть вашим же кодом, но всё равно это заготовка.


  1. Focushift
    15.09.2017 13:48
    +1

    Интересно, под иос можно также сделать? Учитывая что начиная с 8 версии тоже есть улучшенный Webview компонент.


    1. adasoft
      16.09.2017 21:18

      Да, в XCode вроде пример был.


  1. Alex_ME
    15.09.2017 21:10

    И все-таки веб-приложения часто медленные. У меня телефон далеко не первой свежести и гугл-карты в браузере ой как лагают.


    С другой стороны, я очень даже согласен с этим высказыванием: Запрос-ответ-отображение


    1. musicriffstudio Автор
      15.09.2017 21:30

      это зависит от разработчиков.

      В данном примере (даже если просто видео посмотреть не устанавливая) всё летает. И на порядок сложнее просто запрос-ответ. Да и вообще локально работает без всяких запросов.

      Да, нынешний HTML5 это позволяет, многое появилось невиданное ранее. А вот разработчики не меняются.


  1. adasoft
    16.09.2017 21:17

    Ложки дёгтя
    Раз. Вместо WebView из нескольких версий мы получили меганабор разных версий System WebView, каждый со своими прибабахами. Т.е. заранее вообще трудно предагатать, какая версия Webview стоит у пользователя и можно только порекомендовать обновить его до текущей, которая присутствует в сторе.

    Два. Webview это не бразуер. Т.е. весь функционал, который есть в браузере не работает. А значит снова привет решения аля плагины Кордова. А это камера, работа с файлами и другое взаимодействия с железом.

    Три. Подобное решение имеет право на жизнь, можно даже написать свою версию с рюшечками и впнами. Но Кордова опять таки дает чуть больше — например выход сразу на две платформы — Андроид и iOS (а для любителей Windows Phone и туда тоже). Из одной кодовой базы.


    1. adasoft
      16.09.2017 21:21

      * свою версию браузера.


  1. savostin
    16.09.2017 21:55

    есть полная интеграция с платформой Android

    В статье про это ни слова.


    1. musicriffstudio Автор
      16.09.2017 22:39
      -1

      см. шаг 4


      1. savostin
        17.09.2017 08:41
        -1

        Перехват url это полная интеграция?


        1. musicriffstudio Автор
          17.09.2017 10:17

          Полнее некуда. И полностью в рамках правил установленных операционной системой. Система интентов это сердце межпрограммного взаимодействия Android, см. Intent.

          Или по-вашему «полное» означает некое волшебное колдунство?


          1. wholeman
            18.09.2017 12:48

            Полное — это вызов функций javascript из java и наоборот. Как C++ в QML.


            1. musicriffstudio Автор
              18.09.2017 13:06

              это интеграция javascript и java, что есть несколько другое. Кроме того, см. обсуждение выше, цитата:

              Во многих приложениях это просто не нужно.

              Смысл-то какой встраивать веб-приложения в андроидные .apk?

              У вас есть что-то готовое на HTML5 и прекрасно работающее само по себе (как в примере — импорт и экспорт из .mid, хороший звук, больше десятка живых инструментов, быстрая графика, адаптация под маленький экран и тач) и вам нужно малой кровью положить это в ГуглПлей со всей его инфраструктурой для распространения и монетизации.

              В этом случае всё оправданно.

              А если переделывать доступ к камере с хтмльного на андроидный то проще сразу под андроид и делать, без всякого HTML5.


              1. wholeman
                19.09.2017 08:24

                Интеграцией javascript и java это было бы, если б это было реализовано в самих языках, а не средствами платформы.
                Я думал так сделать HTML-интерфейс для своего спортивного приложения, работающего с различными датчиками, встроенными, BTLE и ANT+. Но, похоже, WebView/WebChromeClient такой возможности не предоставляют.


                1. musicriffstudio Автор
                  19.09.2017 09:27

                  ВебВью предоставляет возможность обращения к коду хост-приложения (и наоборот), см. код проекта.

                  HTML5 позволяет обращаться ко многим датчикам напрямую, в том числе и к акселерометру, и к устройствам соединённым по блютуз, искать в гугле.

                  Еще раз попытайтесь понять написанное — если у вас используется то чего нет в HTML5 то смысла писать анроидное приложение на HTML5 просто нет.


                  1. wholeman
                    19.09.2017 10:17

                    Я, всё же, предпочитаю документацию. Вот здесь virpool подходящую ссылочку дал, спасибо ему за это. Я это почему-то пропустил.

                    Я в курсе. Но, во-первых, это только часть датчиков: общаться по ANT+ JS не умеет, а во-вторых мне нужно, чтобы это работало в фоне, что для JS неестественно.

                    Ваш кейс я вполне понял, а Вы мой даже не знаете.) Я хочу иметь возможность значительно менять внешний вид приложения, и здесь гибридное приложение подходит намного лучше, чем чисто нативное или HTML.