Что нового в Web In Play

Опубликовано: 2 декабря 2020 г.

С момента появления Trusted Web Activity команда Chrome упростила использование Bubblewrap. Мы добавили дополнительные функции, такие как интеграция с Google Play Billing , и позволили ему работать на большем количестве платформ, таких как ChromeOS .

Функции Bubblewrap и Trusted Web Activity

Bubblewrap помогает создавать приложения, которые запускают PWA внутри доверенной веб-активности, не требуя знания инструментов для конкретной платформы.

Упрощенный процесс настройки

Раньше для использования Bubblewrap требовалась ручная настройка Java Development Kit и Android SDK, оба из которых подвержены ошибкам. Теперь инструмент предлагает автоматическую загрузку внешних зависимостей при первом запуске.

Вы по-прежнему можете использовать существующую установку зависимостей, если хотите, а новая команда doctor помогает находить проблемы и рекомендует исправления конфигурации, которую теперь можно обновить из командной строки с помощью команды updateConfig .

Улучшенный мастер

При создании проекта с помощью init Bubblewrap необходима информация для создания приложения Android. Инструмент извлекает значения из манифеста веб-приложения и, где это возможно, предоставляет значения по умолчанию.

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

Отображение полноэкранного режима и поддержка ориентации

В некоторых случаях вам может потребоваться, чтобы ваше приложение использовало как можно большую часть экрана, и при создании PWA это реализуется путем установки поля display из манифеста веб-приложения на fullscreen .

Когда Bubblewrap обнаруживает полноэкранный режим в манифесте веб-приложения, он настраивает приложение Android для запуска в полноэкранном режиме или режиме погружения , в терминах, специфичных для Android.

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

Вы можете настроить обе конфигурации как часть процесса bubblewrap init оболочки.

Вывод AppBundles

App Bundles – это формат публикации приложений, который делегирует создание окончательного APK-файла и его подписание в Play. На практике это позволяет предоставлять пользователям файлы меньшего размера при загрузке приложения из магазина.

Bubblewrap теперь упаковывает приложение как App Bundle в файл с именем app-release-bundle.aab . Вам следует предпочесть этот формат при публикации приложений в Play Store, поскольку с 2021 года этого требует магазин .

Делегирование геолокации

Пользователи ожидают, что приложения, установленные на их устройствах, будут работать стабильно, независимо от технологии. При использовании внутри доверенной веб-активности разрешение GeoLocation теперь можно делегировать операционной системе, и, если оно включено, пользователи видят те же диалоговые окна, что и приложения, созданные с помощью Kotlin или Java, и находят элементы управления для управления разрешением в том же месте.

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

Оптимизированные двоичные файлы

Устройства с ограниченным объемом памяти распространены в некоторых регионах мира, и владельцы этих устройств часто предпочитают приложения меньшего размера. Приложения, использующие Trusted Web Activity, создают небольшие двоичные файлы, что избавляет пользователей от некоторого беспокойства.

Bubblewrap был оптимизирован за счет сокращения списка необходимых библиотек Android, в результате чего генерируемые двоичные файлы стали на 800 тысяч меньше. На практике это меньше половины среднего размера, созданного предыдущими версиями. Чтобы воспользоваться преимуществами небольших двоичных файлов, вам нужно всего лишь обновить свое приложение, используя последнюю версию Bubblewrap.

Как обновить существующее приложение

Приложение, созданное с помощью Bubblewrap, состоит из веб-приложения и облегченной оболочки Android, которая открывает PWA. Несмотря на то, что PWA, открываемое внутри доверенной веб-активности, следует тем же циклам обновления, что и любое веб-приложение, встроенную оболочку можно и нужно обновлять.

Вам следует обновить свое приложение, чтобы убедиться, что оно использует последнюю версию оболочки с последними исправлениями ошибок и функциями. Если установлена ​​последняя версия Bubblewrap, команда update применяет последнюю версию оболочки к существующему проекту:

npm update -g @bubblewrap/cli
bubblewrap update
bubblewrap build

Еще одна причина обновлять эти приложения — гарантировать, что изменения в веб-манифесте будут применены к приложению. Используйте для этого новую команду merge :

bubblewrap merge
bubblewrap update
bubblewrap build

Обновления критериев качества

В Chrome 86 внесены изменения в критерии качества доверенной веб-активности, которые полностью описаны в разделе «Изменения критериев качества для PWA, использующих доверенную веб-активность» .

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

  • Невозможность проверки ссылок на цифровые активы при запуске приложения.
  • Невозможность возврата HTTP 200 для запроса автономного сетевого ресурса.
  • Возврат ошибки HTTP 404 или 5xx в приложении.

Помимо проверки того, что приложение прошло проверку ссылок на цифровые активы , остальные сценарии могут быть обработаны сервисным работником:

self.addEventListener('fetch', event => {
  event.respondWith((async () => {
    try {
      return await fetchAndHandleError(event.request);
    } catch {
      // Failed to load from the network. User is offline or the response
      // has a status code that triggers the Quality Criteria.
      // Try loading from cache.
      const cachedResponse = await caches.match(event.request);
      if (cachedResponse) {
        return cachedResponse;
      }
      // Response was not found on the cache. Send the error / offline
      // page. OFFLINE_PAGE should be pre-cached when the service worker
      // is activated.
      return await caches.match(OFFLINE_PAGE);
    }
  })());
});

async function fetchAndHandleError(request) {
  const cache = await caches.open(RUNTIME_CACHE);
  const response = await fetch(request);

  // Throw an error if the response returns one of the status
  // that trigger the Quality Criteria.
  if (response.status === 404 ||
      response.status >= 500 && response.status < 600) {
    throw new Error(`Server responded with status: ${response.status}`);
  }

  // Cache the response if the request is successful.
  cache.put(request, response.clone());
  return response;
}

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

export class FallbackOnErrorPlugin {
  constructor(offlineFallbackUrl, notFoundFallbackUrl, serverErrorFallbackUrl) {
    this.notFoundFallbackUrl = notFoundFallbackUrl;
    this.offlineFallbackUrl = offlineFallbackUrl;
    this.serverErrorFallbackUrl = serverErrorFallbackUrl;
  }

  checkTrustedWebActivityCrash(response) {
    if (response.status === 404 || response.status >= 500 && response.status <= 600) {
      const type = response.status === 404 ? 'E_NOT_FOUND' : 'E_SERVER_ERROR';
      const error = new Error(`Invalid response status (${response.status})`);
      error.type = type;
      throw error;
    }
  }

  // This is called whenever there's a network response,
  // but we want special behavior for 404 and 5**.
  fetchDidSucceed({response}) {
    // Cause a crash if this is a Trusted Web Activity crash.
    this.checkTrustedWebActivityCrash(response);

    // If it's a good response, it can be used as-is.
    return response;
  }

  // This callback is new in Workbox v6, and is triggered whenever
  // an error (including a NetworkError) is thrown when a handler runs.
  handlerDidError(details) {
    let fallbackURL;
    switch (details.error.details.error.type) {
      case 'E_NOT_FOUND': fallbackURL = this.notFoundFallbackUrl; break;
      case 'E_SERVER_ERROR': fallbackURL = this.serverErrorFallbackUrl; break;
      default: fallbackURL = this.offlineFallbackUrl;
    }

    return caches.match(fallbackURL, {
      // Use ignoreSearch as a shortcut to work with precached URLs
      // that have _WB_REVISION parameters.
      ignoreSearch: true,
    });
  }
}