Среди многообразия инструментов, анонсированных на Android Dev Summit, особое внимание хочется уделить механизму обновления приложения In-App Updates (IAUs), который помогает разработчикам ускорить добавление новых фич, баг-фиксов и улучшений производительности. Поскольку эта функциональность была опубликована после Google I/O 2019, в этой статье я подробно расскажу об IAUs, опишу рекомендованные схемы реализации и приведу некоторые примеры кода. Также я расскажу о нашем опыте интеграции IAUs в Pandao, приложение для заказа товаров из Китая.

Новый API позволяет разработчикам инициировать обновление приложения до последней доступной в Google Play версии. Таким образом IAUs дополняет уже существующий механизм автоматического обновления Google Play. IAUs содержит несколько схем реализации, которые принципиально различаются с точки зрения взаимодействия с пользователем.

  1. Flexible Flow предлагает пользователям скачать обновление в фоновом режиме и установить в удобное для пользователя время. Он предназначен для случаев, когда пользователи всё ещё могут использовать старую версию, но уже доступна новая.


  2. Immediate Flow требует от пользователей скачать и установить обновление, прежде чем продолжить использование приложения. Он предназначен для случаев, когда для разработчиков критически важно обновить приложение.



Поскольку второй вариант не так важен и меньше подходит для приложения Pandao, разберём подробнее сценарий Flexible Flow.

Интеграция IAUs Flexible Flow


Варианты использования


Процесс обновления с помощью IAUs состоит из нескольких шагов.

  1. Приложение с помощью библиотеки Play Core, которая проверяет в Google Play, есть ли доступные обновления.
  2. Если они есть, то приложение просит Google Play показать диалог IAUs. Google Play показывает пользователю диалог с предложением обновиться.
  3. Если пользователь соглашается, Google Play в фоновом режиме скачивает обновление, показывая пользователю в статус-баре прогресс скачивания.
  4. Если скачивание завершилось, когда приложение работает в фоновом режиме, Google Play автоматически завершает установку. Если же приложение в этот момент активно, то для таких случаев нужно определять собственную логику завершения установки. Рассмотрим следующие сценарии.
    1. Приложение запускает процесс установки, показав пользователю диалог Google Play с индикатором прогресса. После завершения установки запускается обновленная версия приложения. В этом случае рекомендуется отобразить дополнительный диалог, который позволит пользователю подтвердить, что он готов сейчас перезапустить приложение. Это рекомендуемая схема реализации.
    2. Приложение ждёт, пока оно окажется в фоновом режиме, и после этого завершает обновление. С одной стороны, это менее навязчивое поведение с точки зрения UX, так как взаимодействие пользователя с приложением не прерывается. Но с другой — оно требует от разработчика реализовать логику для определения того, находится ли приложение в фоновом режиме.

Если установка скачанного обновления не была завершена, то Google Play может завершить установку в фоновом режиме. Данный вариант лучше не использовать явно, потому что он не гарантирует установки обновления.

Основные требования к тестированию


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

  • Исходная версия с более высоким номером должна быть опубликована в Google Play, она будет идентифицирована Google Play как доступное обновление. Целевая версия с более низким номером сборки и интегрированным IAUs должна быть установлена на устройстве, её мы будем обновлять. Суть в том, что когда приложение попросит Google Play проверить наличие обновления, он сравнит номера сборок у установленной и доступной версии. Так что IAUs будет запущено только в том случае, если номер сборки в Google Play выше, чем у текущей версии на устройстве.
  • Исходная и целевая версии должны иметь одинаковые имена пакета и должны быть подписаны одинаковым релизным сертификатом.
  • Android 5.0 (API level 21) или выше.
  • Библиотека Play Core 1.5.0 или выше.

Пример кода


Здесь мы рассмотрим пример кода для использования IAUs Flexible Flow, который также можно найти в официальной документации. Для начала необходимо добавить библиотеку Play Core в build.gradle файл на уровне модуля.

dependencies {
   ...
   implementation "com.google.android.play:core:1.5.0"
}

Затем создадим экземпляр AppUpdateManager и добавим функцию обратного вызова к AppUpdateInfo, в которой будет возвращаться информация о доступности обновления, объект для запуска обновления (если оно доступно) и текущий прогресс скачивания, если оно уже началось.

// Create instance of the IAUs manager.
val appUpdateManager = AppUpdateManagerFactory.create(context)

// Add state listener to app update info task.
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
    // If there is an update available, prepare to promote it.
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
        // ...
    }

    // If the process of downloading is finished, start the completion flow.
    if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
        // ...
    }
}
    .addOnFailureListener { e ->
        // Handle the error.
    }

Чтобы показать диалог для запроса обновления из Google Play, необходимо передать полученный объект AppUpdateInfo в метод startIntentSenderForResult.

   appUpdateManager.startUpdateFlowForResult(
          // Pass the intent that is returned by 'getAppUpdateInfo()'.
           appUpdateInfo,
           // Or 'AppUpdateType.IMMEDIATE for immediate updates.
           AppUpdateType.FLEXIBLE,
          // The current activity.
           activity,
           REQUEST_CODE
   )

Для отслеживания состояния обновления можно добавить в менеджер IAUs слушатель событий InstallStateUpdatedListener.

// Create a listener to track downloading state updates.
val listener = InstallStateUpdatedListener { state -> 
    // Update progress indicator, request user to approve app reload, etc.
}

// At some point before starting an update, register a listener for updates.
appUpdateManager.registerListener(listener)

// ...

// At some point when status updates are no longer needed, unregister the listener.
appUpdateManager.unregisterListener(listener)

Как только обновление будет скачано (статус DOWNLOADED), нужно перезапустить приложение, чтобы завершить обновление. Перезапуск можно инициировать с помощью вызова appUpdateManager.completeUpdate(), но перед этим рекомендуется показать диалоговое окно, чтобы пользователь явно подтвердил свою готовность к перезапуску приложения.

Snackbar.make(
    rootView,
    "An update has just been downloaded from Google Play",
    Snackbar.LENGTH_INDEFINITE
).apply {
    setAction("RELOAD") { appUpdateManager.completeUpdate() }
    show()
}

Ошибка «Update is Not Available»


Во-первых, перепроверьте соответствие требованиям, перечисленным в разделе «Basic Implementation Requirements». Если вы все выполнили, однако обновление согласно вызову onSuccess, всё же недоступно, то проблема может быть в кэшировании. Вполне вероятно, что приложение Google Play не знает о доступном обновлении из-за внутреннего механизма кэширования. Чтобы избежать этого при ручном тестировании, вы можете принудительно сбросить кэш, зайдя на страницу «Мои приложения и игры» в Google Play. Или можете просто очистить кэш в настройках приложения Google Play. Обратите внимание, что эта проблема возникает только в ходе тестирования, она не должна влиять на конечных пользователей, поскольку у них кэш всё равно обновляется ежедневно.

IAUs Flexible Flow в приложении Pandao


Мы участвовали в программе раннего доступа и интегрировали IAUs Flexible Flow (рекомендованная реализация) в приложение Pandao — платформу, на которой производители и вендоры могут торговать китайскими товарами. Диалог IAUs отображался на главном экране, так что с ним могло взаимодействовать максимальное количество пользователей. Изначально мы хотели показывать диалог не чаще раза в день, чтобы не отвлекать людей от взаимодействия с приложением.

Поскольку A/B-тестирование играет ключевую роль в жизненном цикле любой новой фичи, мы решили оценить эффект от IAUs в нашем приложении. Мы случайным образом разделили пользователей на две непересекающиеся группы. Первая была контрольной, без использования IAUs, а вторая группа была тестовой, этим пользователям мы показывали диалог IAUs.


A/B-тест IAUs Flexible Flow в приложении Pandao.

В течение последних нескольких релизов мы измерили долю активных пользователей каждой версии приложения. Оказалось, что среди активных пользователей с последней доступной на тот момент версией основную часть составляли участники из группы B, то есть с функцией IAU. Фиолетовая линия на графике показывает, что в первые дни после публикации версии 1.29.1 количество активных пользователей с IAUs превысило количество пользователей без этой функции. Поэтому можно утверждать, что пользователи с IAUs быстрее обновляют приложение.


Диалог IAUs Flexible Flow в приложении Pandao.

Согласно нашим данным (см. график выше), пользователи больше всего кликают на кнопку подтверждения в диалоге IAUs в первые дни после релиза, а затем конверсия постоянно снижается вплоть до публикации следующей версии приложения. То же самое наблюдается с кнопкой установки в диалоговом окне, которая инициирует установку скачанного обновления. Следовательно, можно сказать, что среднее значение конверсии в обоих случаях прямо пропорционально частоте релизов. В Pandao средняя конверсия в течение одного месяца достигает 35 % для клика на кнопку подтверждения и 7 % для клика на кнопку установки.

Мы предполагаем, что уменьшение доли подтверждений с течением времени — лишь проблема пользовательского опыта, потому что люди, которым интересна новая версия, будут обновляться довольно быстро, а те, кто не интересуются обновлением, так и не станут интересоваться. Исходя из этого предположения, мы решили не беспокоить тех, кому не интересно обновление, и не спрашивать их каждый день. Хорошей практикой будет использование другой логики запросов, которая основывается на «устаревании», то есть чтобы не беспокоить пользователей, мы оцениваем, насколько старые версии стоят у них и как часто мы уже предлагали им обновиться.

В целом IAUs продемонстрировала хорошие результаты в ходе A/B-тестирования, так что мы раскатили IAUs для всех пользователей.

Благодарности


Благодарю за помощь в написании статьи Марину Плешкову Maryna_Pliashkova, Александра Черного alexchernyy, Илью Назарова RolaRko, Глеба Бодячевского, Даниила Полозова jokerdab, Анастасию Кулик, Владислава Бреуса и Владислава Голдина Vladiskus.

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


  1. prs123
    17.05.2019 12:47

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


  1. forewar
    17.05.2019 17:28

    Тестовой группе вы показывали диалог IAUs.
    А контрольной группе сообщений с предложением обновиться не было?


    1. sismetanin Автор
      17.05.2019 20:32

      Да, все верно.


      1. forewar
        17.05.2019 22:38

        Поэтому можно утверждать, что пользователи с IAU быстрее обновляют приложение.

        Так может быть пользователи обновлялись не потому что вы внедрили супер фоновый режим IAUs, а просто потому что предложили обновиться?