Альтернатива webview android system

Crosswalk Project — замена Android WebView. Интеграция в проект

Эта статья откроет небольшой цикл из двух частей, посвященных интересному проекту под названием Crosswalk Project. В них я затрону вопросы интеграции Crosswalk в Android приложение и использовании его как замену системного WebView в обычном приложении.

Под «обычным» я подразумеваю классический проект на Java с использованием Android SDK, в противовес HTML5 приложениям и нативному C++ коду. А т.к. Crosswalk в основном используется как runtime запуска HTML5 приложений, то, чтобы не путаться в терминах, буду называть этот проект обычным.

В первой части я хочу рассказать непосредственно об интеграции Crosswalk в Android приложение и использовании Crosswalk WebView вместо системного Android WebView. Во второй части я опишу некоторые нюансы и сложности в работе с Crosswalk при интеграции, а также сделаю общие выводы.

Что же такое Crosswalk?

Crosswalk Project — это runtime построенный на технологиях open source для HTML приложений. Основой для Crosswalk Project служит Google Chromium. Crosswalk Project также и сам является open source проектом и распространяется под BSD License.

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

Применяя Crosswalk вы сможете:

  • Использовать все возможности, доступные в современных web браузерах: HTML5, CSS3, JavaScript.
  • Иметь доступ к последним рекомендованным и развивающимся web стандартам.
  • Использовать экспериментальные API, недоступные в большинстве основных web браузеров.
  • Контролировать цикл обновления приложения путем распространения с собственной средой выполнения.
  • Добавлять специальные расширения к приложению для увеличения количества специфических особенностей не предоставляемых Crosswalk или стандартной web платформой.

Итак Crosswalk в первую очередь нацелен на использование в качестве runtime для HTML5 приложений и интегрирован с Cordova начиная с версии 4.0. Поэтому он достаточно хорошо известен среди разработчиков гибридных приложений, но, возможно, не так хорошо в среде Java разработки.

Crosswalk может использоваться как замена системного WebView в обычном Android проекте. Официально Crosswalk поддерживает все версии Android начиная с 4.0 и выше. В этом случае мы получаем самостоятельный браузер, который позволит нам не зависеть от версии Android и ограничений реализации WebView в этой версии системы.

Компоненты Crosswalk.

Создатели Crosswalk не предполагали своей целью полную совместимость с системным WebView. Однако, в общем мы имеем достаточно близкую копию интерфейсов системного браузера до версии Android 4.4, с которой системный WebView также начал базироваться на Chromium. Поэтому, и к большому сожалению, в Crosswalk вы не найдете очень удобного и доступного с Android API 21 вызова:

С версии Crosswalk 10 авторы решили еще дальше отойти от стандартных интерфейсов и добавили некоторые дополнительные вызовы в свой публичный API. Javadoc для различных версий Crosswalk вы можете найти на официальном сайте, ниже я рассмотрю несколько важных моментов для 14ой версии, последней релизной версии на данный момент.

Сейчас Crosswalk содержит собственно сам Crosswalk WebView (или XWalkView), а также:

  • XWalkResourceClient — калбэки и события при загрузке ресурсов.
  • XwalkUIClient — калбэки и события для UI.
  • XWalkNavigationHistory — история переходов в XWalkView.
  • XWalkPreferences — настройки среды Crosswalk.
  • JavascriptInterface — аннотация для методов, которые будут доступны из JavaScript. Идентична системной аннотации.

Кроме перечисленных выше классов имеется несколько вспомогательных классов и классов облегчающих интеграцию в приложение-браузер, но не использовавшихся мной. Например, XWalkApplication и XWalkActivity.

Интеграция Crosswalk в проект.

Исходный код с интегрированным XWalkView и описанными решениями доступен в GitHub.

В целом интеграция Crosswalk достаточно проста, если вам необходимо интегрировать Crosswalk в проект разрабатываемый с помощью Eclipse/ADT, то есть отличный официальный гайд по этому поводу. Здесь мы рассмотрим интеграцию в проект с использованием Android Studio. По сути она заключается в подключении библиотеки Crosswalk, все остальные операции не сильно отличаются от использования стандартного WebView.

Читайте также:  Геншин импакт последняя версия андроид

1. Необходимо создать новый проект в Android Studio. Я, для примера, создал проект с пустой Activity и поддержкой начиная с API 14.

2. Подключить репозиторий со сборками Crosswalk и выбрать саму сборку проекта. Я использую последнюю доступную с версией 14.43.343.17:

3. Добавить в AndroidManifest.xml разрешения для использования сети и т.д.:

Полный список разрешений описан в официальном гайде, указанном выше. Он включает в себя доступ к местоположению, камере, записи аудио. Для простой реализации браузера все они не нужны. В примере указываем только разрешения для доступа собственно в интернет и записи в хранилище, для хранения кэша Crosswalk.

4. Добавить XWalkView в layout там, где вы хотите его использовать. Простой пример:

5. Для загрузки url в коде вашей Activity необходимо добавить следующие вызовы:

6. Аналогично системному WebView, можно подключить классы для получения оповещений от XWalkView:

Дополнительно, если вы хотите использовать XWalkView как базу для своего HTML5 приложения, можно переопределить методы onActivityResult, onNewIntent и другие для трансляции сообщений в Crosswalk. Например, onActivityResult используется в том числе для обработки событий от JavaScript диалоговых окон. К этому можно добавить, что для HTML5 приложений имеет смысл наследоваться от XWalkActivity, в котором уже реализованы все нужные моменты.

Некоторые нюансы реализации.

Приведу несколько моментов реализации Crosswalk, на которые сразу стоит обратить внимание:

  • XWalkView использует SurfaceView либо TextureView для отрисовки. Поэтому оно достаточно быстро отрисовывается как на устройствах, так и в эмуляторе. Однако, это создает проблемы при анимации и работе с изображением XWalkView.
  • Базовым view является SurfaceView, если вы хотите анимировать XWalkView, то необходимо использовать TextureView. Для выбора необходимо установить параметр через класс XWalkPreferences, до создания самого XWalkView:
  • XWalkPreferences не являются аналогом WebSettings и содержит настройки для среды Crosswalk. WebSettings в явном виде недоступен, все стандартные параметры уже включены по дефолту (поддержка JavaScript и пр.).
  • История переходов не доступна из самого XWalkView и контролируется классом XWalkNavigationHistory. Если вы хотите перейти назад или вперед, узнать возможен ли переход и т.д., нужно использовать следующие методы:
  • Методы setResourceClient() и setUIClient() не принимают null как параметр, в отличии от стандартных. Поэтому таким образом не получится отключить оповещения, только установкой «пустых» классов или уничтожением самого XWalkView.
  • Более сложные моменты и их возможные решения я описал во второй статье, чтобы не углубляться при быстром ознакомлении.

    Источник

    Crosswalk Project — замена Android WebView. Проблемы интеграции

    В этой статье я закончу свой рассказ о проекте Crosswalk Project (первую часть вы можете найти здесь). Расскажу более детально о своем опыте интеграции Crosswalk, некоторых тонкостях при работе с ним, встреченных проблемах и их возможных решениях.

    Первое и, возможно, самое очевидно решение всех вопросов — это изменение кода Crosswalk под свои нужды. Это возможно, т.к. проект открытый и даже можно помочь его авторам. Однако, нужно это не всегда и может вызвать дополнительные затруднения. В описываемых примерах такой вариант я не рассматриваю, но изучить код базовых классов полезно.

    Контроль загрузки страницы в XWalkView.

    Пожалуй второй наиболее важной вещью в Crosswalk, после скорости его работы, является предсказуемость вызова калбэков. Возможность ориентироваться на логику вызовов и иметь единый алгоритм для всех версий Android — это просто отлично. Сложности же с контролем загрузки в системном WebView хорошо описаны в этой статье.

    Также как и системный класс, XWalkView имеет два вспомогательных класса, которые могут получать вызовы во время загрузки и работы с XWalkView — это XWalkUIClient и XWalkResourceClient. Как я писал ранее, они не имеют прямого соответствия системным WebChromeClient и WebViewClient, методы в них распределены несколько иначе. Однако, для себя я установил примерное соответствие как WebChromeClient == XWalkUIClient и WebViewClient == XWalkResourceClient.

    XWalkUIClient в том числе содержит методы:

    • onPageLoadStarted — информирует о начале загрузки основного фрэйма.
    • onPageLoadStopped — информирует об окончании загрузки основного фрэйма.
    Читайте также:  Может андроид видеть флешку

    а также:

    • onConsoleMessage
    • onReceivedTitle
    • onConsoleMessage
    • onRequestFocus
    • shouldOverrideKeyEvent

    Кака видно, здесь присутствуют методы входящие как в интерфейс WebViewClient, так и WebChromeClient, но, в целом, XWalkUIClient содержит методы имеющие важность для UI.

    XWalkResourceClient в том числе содержит:

    • onDocumentLoadedInFrame — информирует о том, что HTML документ получен и обработан, вызывается не дожидаясь загрузки css, изображений и т.д. NB! Замечу, что метод описан в Javadoc и реализован в master ветке, но отсутствует сейчас в классе при интеграции.
    • onLoadStarted — информирует о том, что началась загрузка ресурса по указанному url.
    • onLoadFinished — информирует о том, что завершилась загрузка ресурса по указанному url.
    • onProgressChanged — информирует о проценте загрузки страницы.
    • shouldInterceptLoadRequest — аналогично системному калбэку, позволяет клиенту вернуть данные для казанного url.
    • shouldOverrideUrlLoading — аналогично системному калбэку, позволяет клиенту перехватить контроль перед загрузкой ресурса.

    Последовательность вызова основных калбэков выглядит так:

    • shouldOverrideUrlLoading — для указанного url;
    • onPageLoadStarted;
    • shouldInterceptLoadRequest — загрузка основной страницы;
    • onLoadStarted — загрузка основной страницы (дублирует shouldInterceptLoadRequest);
    • shouldInterceptLoadRequest в паре с onLoadStarted — загрузка ресурсов, для каждого ресурса;
    • onPageLoadStopped;
    • onLoadFinished.

    Данная последовательность будет аналогична как для url загруженного с помощью метода WXalkView, так и для перехода по ссылке на странице и даже при остановке загрузки с помощью stopLoading().

    Практически аналогично выглядит последовательность для загрузки страницы с редиректом:

    • shouldOverrideUrlLoading — для указанного url;
    • onPageLoadStarted;
    • shouldInterceptLoadRequest — загрузка основной страницы;
    • onLoadStarted — загрузка основной страницы;
    • shouldOverrideUrlLoading — для url, указанного в редиректе;
    • onPageLoadStarted;
    • shouldInterceptLoadRequest в паре с onLoadStarted — загрузка ресурсов;
    • onPageLoadStopped;
    • onLoadFinished.

    Как видно, при переходе по редиректу мы получили дополнительные вызовы тех же стартовых калбэков и, по сути, логика в этом случае тоже не нарушилась.

    Дополнительно можно указать, что метод onPageLoadStopped имеет следующую сигнатуру:

    Дополнительный параметр типа XWalkUIClient.LoadStatus дает достаточно важную информацию о том, как закончилась загрузка и имеет 3 варианта:

    • CANCELLED — в случае вызова stopLoading();
    • FAILED — в случае ошибки загрузки;
    • FINISHED — нормальное завершение загрузки.

    Необошлось и без пары странностей в поведении Crosswalk. Например, метод onLoadFinished вызывается только один раз после загрузки всей страницы и даже после onPageLoadStopped. Логика предполагает, что вызов onLoadFinished должен соответствовать вызову onLoadStarted, который происходит для каждого ресурса, но сейчас это не так.

    Также возможна ситуация когда произойдет двукратный вызов пары финальных методов onPageLoadStopped и onLoadFinished. Упоминание о таком поведении я нашел еще для Crosswalk 11ой версии, но очевидно с этой проблемой не справились до сих пор.

    Обработка событий от экрана и кнопок.

    Одной из первых проблем с которой вы столкнетесь при интеграции XWalkView будет обработка событий экрана и клавиатуры (конкретно кнопки Back). В XWalkView, также как и методы onActivityResult и onNewIntent, реализован метод: dispatchKeyEvent(KeyEvent event). В нем происходит перехват события от кнопки Back для перехода из полноэкранного режима и перехода по истории браузера. Соответственно вы не сможете получить это событие, если вы используете методы:

    Вариантом решения может быть обработка этого события также в dispatchKeyEvent(KeyEvent event). Это также полезно знать, если вы хотите реализовать собственный переход по истории навигации.

    Аналогичная проблема ожидает вас, если вы хотите использовать onTouchEvent listener для вашего XWalkView. Решение аналогично приведенному выше — реализуйте обработку события в dispatchTouchEvent(MotionEvent event).

    Примеры добавлены в тестовый проект, доступный в GitHub.

    Важным моментом в работе браузера и WebView является обработка cookies. Например, вы хотите загрузить какую-то страницу не через XWalkView, но отобразить ее в нем и предоставить пользователю возможность с ней работать. Страница может устанавливать свои cookies и для нормальной работы они понадобятся в XWalkView.

    В Crosswalk существует специальный компонент XWalkCookieManager, который собственно и занимается хранением и работой с cookies. Очень странно, но он не описан в Javadoc, хотя и является публичным и доступным для использования. Реализацию и комментарии к методам класса можно найти здесь.

    Читайте также:  Вход по отпечатку пальца сбербанк андроид как настроить

    XWalkCookieManager, как и кэш Crosswalk, един для всех инстансов XWalkView в вашем приложении. Класс достаточно прост в использовании и позволяет добавлять и получать cookie для определенного адреса, очистить хранилище и пр. Пример инициализации:

    Однако простота его реализации имеет и некоторые проблемы. Например, метод для установки cookie выглядит так:

    Соответсвенно вы не сможете указать время жизни для cookie, а domain и path для cookie будут получены из указанного url, но с некоторыми неприятными нюансами.

    Например, вы хотите установить cookie для адреса m.vk.com и предполагаете, что установленная cookie будет действительна и для адреса login.vk.com, но в нашем случае это не так. Для того, чтобы XWalkCookieManager адекватно отработал этот момент необходимо устанавливать cookie для адреса .vk.com.

    Также заявлено, что XWalkCookieManager должен обновить cookie, если вы устанавливаете уже имеющуюся в хранилище, но я наблюдал, что иногда он дублирует значения. Очевидно какие-то проблемы в разборе value при установке. Поэтому стоит лишний раз проверить корректность работы этого классы, если вы пользуетесь им.

    В качестве простого примера работы с XWalkCookieManager, в тестовом проекте реализован метод синхронизации с CookieManager.

    Получение WebSettings и их установка.

    Как я уже писал ранее, WebSettings не доступны при работе с XWalkView и имеют заранее предустановленные параметры. Точнее в Crosswalk имеется аналог этого класса — XWalkSettings, его методы вы можете изучить здесь. Для некоторых параметров было сделано исключение и они вынесены в интерфейс самого класса XWalkView. Например, сейчас вы можете установить нужный вам User-Agent.

    Однако, может возникнуть необходимость более тонкой настройки. Также может возникнуть необходимость, как в моем случае, получить User-Agent, используемый самим XWalkView. В таком случае можно воспользоваться возможностью получить его через reflection.

    Собственно сам класс XWalkView является надстройкой над реализацией XWalkViewInternal и соединяется с ней посредством bridge через reflection. XWalkViewInternal же имеет публичный метод getSettings(), что мы и можем использовать:

    В качестве примера получения XWalkSettings и работы с ним, в тестовом проекте реализован метод получения User-Agent.

    Получение изображения XWalkView.

    Поскольку XWalkView использует для отрисовки SurfaceView или TextureView, то нет возможности получить его изображение стандартными методами. Например, такой вариант работает для системного WebView, но не работает для XWalkView:

    Происходит это т.к. стандартные методы view, типа getDrawingCache() или draw(), работают с software layer, а в XWalkView используется hardware layer. Именно поэтому разработчики просят установить флаг android:hardwareAccelerated=«true» для приложений использующих Crosswalk. К слову, сейчас он устанавливается по дефолту и отдельно его прописывать нет необходимости.

    Получить изображение XWalkView возможно при использовании в качестве основы TextureView, где имеется метод getBitmap(). В кратце, для этого необходимо найти в дереве целевой TextureView и уже у него вызвать этот метод. Пример реализации также доступен в тестовом проекте.

    Мелкие нюансы.

    В довесок несколько мелких моментов, которые вам также могут встретиться в процессе интеграции:

      Если вы заменяете системный WebView в старом проекте и используете аннотацию JavascriptInterface, не забудьте исправить импорт. Иначе получите ошибки во время выполнения JavaScript кода. Соответственно:

    Если вы используете несколько XWalkView, используете его во фрагментах или в каких-то других, более сложных чем в примере, условиях. В этом случае может возникнуть ситуация когда необходимо будет прямо вызывать методы для пробуждения таймеров XWalkView, после возобновления работы с ним:

    Выводы

    Использовать Crosswalk в разработке достаточно просто и удобно, особенно учитывая открытый исходный код. Неплохое комьюнити и достаточно большое распространение проекта позволят решить большинство проблем.

    Если вы поддерживаете Android 4.0+ и хотите более предсказуемой работы вашего кода на всех версиях Android, то я определенно рекомендую Crosswalk.

    Если же вы поддерживаете Android с версии 4.4 и тем более 5.0, то я бы задумался о применении Crosswalk в своих проектах. Отсутствие некоторых новых возможностей системного WebView может осложнить вам жизнь.

    Надеюсь мой опыт поможет вам определиться, что же использовать в качестве WebView для вашего проекта :).

    Источник

    Оцените статью