Как заменить android webview

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 — нормальное завершение загрузки.
Читайте также:  Сбербанк мир nfc android оплата смартфоном

Необошлось и без пары странностей в поведении 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 для вашего проекта :).

Источник

«Ремонт» Android System WebView

Александр Носков

О пресловутом приложении Android System WebView, проблемах и попытках их решения.

Каждый пользователь Android-смартфона видит уведомление об обновлении приложения Android System WebView так же часто, как обновление безопасности Android. И тому есть причины, но прежде давайте разберемся, что это за штука такая и что она делает.

WebView

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

Неважно, какой это браузер, Safari, Internet Explorer, Chrome, Firefox или Edge, производителю для изменения элементов управления необходимо обновить локальное приложение. Для изменения отображения (разметки) контента достаточно обновить только компонент WebView. Программисты называют этот компонент встраиваемым браузером, который нативное приложение может использовать для отображения web-контента, но это слишком скучно и непонятно звучит. Часть движка браузера – это звучит гораздо понятнее и логичнее ввиду отсутствия популярных браузеров, которые не используют WebView.

Android System WebView

В отличие от классического десктопного понимания, в операционной системе Android компонент WebView оформлен в виде отдельного приложения и кроме стандартной функции работы с браузером отвечает за показ рекламы во всех приложениях, включая сторонние. Да-да, это та самая «бяка», которая прерывает игру неуместными рекламными вставками, отвлекает от прочтения новостей и с каждым обновлением при web-серфинге выводит вверх все больше ссылок от самой компании Google.

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

Читайте также:  Командные файлы для андроид

Проблемы Android System WebView

Как и с любым системным приложением Android, основные проблемы происходят после очередного обновления. Это выглядит как полный отказ или неправильный старт Android System WebView, а конкретнее – браузер либо сразу «вылетает», либо начинает дергаться, как перебравший текилы дедушка на вечеринке би-боев.

Решение

Из множества решений, которые могут встретиться на просторах интернета, реально работают только четыре. Стандартное, такое же, как для любых других приложений: зайти в настройки смартфона, удалить все обновления Android System WebView. Сразу после этого перезагрузить смартфон и установить обновления заново.

Второе посложнее и потребует навыков работы с ADB, попросите друга, если не справитесь сами. В любом случае все, что вы делаете, вы делаете на свой страх и риск. Вот краткий порядок действий:

  1. Удалите обновления Android System WebView
  2. Загрузите свою (по умолчанию) версию приложения Android System WebView по этой ссылке и закиньте его в папку ADB. Файл должен называться android-system-webview.apk.
  3. В командной строке наберите:
    adb connect IP-OF-device
    adb remount
    adb push android-system-webview.apk /system
    adb shell pm install -r -d /system/android-system-webview.apk

Третий способ требует Root-доступа и по этой причине подойдет не каждому. Рассказывать тут нечего, просто удалите системное приложение Android System WebView. Скачайте по той же ссылке последнюю версию приложения и закиньте ее в системный раздел.

Четвертый способ знают все и он не требует технических навыков. Это сброс смартфона до заводских настроек, со всеми вытекающими последствиями. Применять его следует только если не помогли первые три.

Почему столько внимания?

Мысль написать о проблеме Android System WebView возникла после того, как на глаза стал попадаться один и тот же текст, перепечатываемый из издания в здание. И если к стандартному способу решения проблемы вопросов не возникло, то со вторым просто беда – он просто был не дописан до конца в части отладки по ADB. Все лицемерие раскрывается, когда смотришь на источники – это многочисленные сайты, которые предлагают ремонт Android-смартфонов. Заблудившаяся в тумане бесполезной информации несчастная пользовательская душа в конце концов отнесет свои кровные деньги нечистым на руку дельцам. Разве может нормальный человек стерпеть такое?

Заключение

Напоследок необходимо сказать что-нибудь про главного виновника всех этих сбоев системных приложений. И их несколько, а главным, мне кажется, является компания Google. Каждый год при анонсе новой версии Android компания декларирует минимальные системные требования для устройств. И, по логике вещей, старые смартфоны, умещающиеся в эти рамки, должны продолжать исправно работать долгие годы до полного своего разрушения. К сожалению, этого не происходит, компания не хочет делать широкий жест и удалять свои системные приложения после сроков гарантированного обслуживания конкретной версии ОС (хотя и может это делать технически), количество рекламы и ее «тяжесть» также растут год от года, она становится все «актуальнее». Увы, на руках у граждан все еще очень много смартфонов с 0,5 — 1 ГБ ОЗУ, с накопителем, разделенным на системный и пользовательский разделы. И эти смартфоны получают точно такие же обновления для установленных приложений, как и их флагманские собратья. Похоже, это основные причины сбоев обновления системных приложений – несоответствие жадности главного рекламодателя, выпустившего с начала года уже 21 обновление Android System WebView, и возможностей технического оборудования простых пользователей.

Выскажите свое мнение, стоит ли овчинка выделки? Уместны ли приложения Google в Android-смартфонах? И что вы думаете о бесполезных руководствах по «ремонту», которых в Рунете развелось как грязи?

Источник

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