Хабрахабр

[Из песочницы] Подводные камни разработки Google Play Instant

Меня зовут Камо Сперцян, я занимаюсь Android-разработкой в PROFI. Привет, Хабр! Недавно я написал приложение с мгновенным запуском для наших клиентов. RU. Если вы ещё не знакомы с технологией, приглашаю вас сначала посетить Android Developers.

В сети множество статей о том, как создавать приложения с мгновенным запуском. С презентации Instant Apps (Google Play Instant) на Google I/O 2016 прошло больше двух лет. Но на деле это не совсем так. Судя по ним, ничего сложного в этом нет. Надеюсь, статья окажется полезной разработчикам, которым этот путь ещё предстоит.
Я постараюсь описать основные трудности, через которые мне пришлось пройти от создания пустого проекта до публикации Instant App в Google Play.

Выбор подхода

В большинстве источников описывается процесс конвертирования основного приложения целиком в Instant App. Однако наше приложение никак не соответствовало ограничению в 4 МБ и предоставляло гораздо большую функциональность, чем требовалось для ознакомления с сервисом перед установкой. Сейчас Google в тестовом режиме увеличил допустимый размер приложения с мгновенным запуском до 10 МБ.

Первый — взять готовое приложение и вырезать из него ненужную функциональность. У меня был выбор из двух подходов к созданию Instant App. Посчитав первый вариант быстрым, мы с коллегами опробовали его на локальном хакатоне и тогда же убедились в его безнадёжности. Второй — создать пустой проект и перенести в него функциональность, которая необходима. Во-вторых, размер приложения оказался очень большим из-за лишнего кода и ресурсов. Во-первых, на это ушло много времени (порядка 40 человеко-часов). Мы судорожно пытались уместить получившееся приложение в 4 МБ за время хакатона, и в итоге всё равно не успели. В-третьих, лишний код усложнял сопровождение.

Перенос функциональности

Наученный горьким опытом, я создал пустой проект и стал копировать в него только нужные модули приложения. У нас поддерживается модульная архитектура, поэтому сделать это было несложно. Здесь я столкнулся с первой проблемой — в Instant Apps нельзя использовать сервисы. В моём случае это ограничение не оказалось критичным: мы использовали сервис для загрузки фотографий, а в Instant App от этой фичи отказались, мотивируя пользователей скачать основное приложение. Но этот момент стоит учитывать, если ваше приложение тоже использует сервисы.

В этой статье Google даёт советы на этот случай, но мне они мало помогли. К моему удивлению, полученное копированием только нужных кусков кода приложение всё равно не влезло в допустимые 4 МБ и весило около 5 МБ. Единственное, от чего мы могли отказаться, — кастомные шрифты, но их вес существенно не влиял на размер APK.

Простое включение Тут я вспомнил, что ProGuard у нас в проекте отключён на debug-сборках.

minifyEnabled true

сократило размер приложения чуть ли не вдвое. О чудо — ограничение в 4 МБ соблюдено!

Миграция данных

Далее предстояло решить вопрос с миграцией данных. Как известно, Instant Apps поддерживаются операционной системой Android с версии 5.0. При этом автоматическая миграция данных работает только начиная с Android 8.0. Для этого достаточно использовать в обоих приложениях файлы shared preferences с одинаковым названием. Для версий с 5.0 по 7.1 миграцию нужно писать вручную с помощью Cookie API или Storage API. Я воспользовался Cookie и с особыми проблемами не столкнулся — правда, это потребовало изменений не только на стороне Instant App, но и в устанавливаемом приложении. Так что в итоге пришлось выпустить новую версию приложения и раскатить её на всю аудиторию для релиза Instant App.

Отладка

С отладкой всё оказалось не так просто.

Для меня это означало тестирование на production-серверах, так как все тестовые стенды работали по http. Во-первых, Google Play Instant не поддерживает незащищённые сетевые соединения, так что забудьте про http, только https. Не критично, но приятного мало.

При запусках через Android Studio невозможно проверить обновление Instant App до «полноценного» приложения. Во-вторых, сам запуск Instant App: вы можете тестировать приложение как обычное, устанавливаемое, но лишь до поры до времени. Для этого нужно запускать приложение с мгновенным запуском именно как Instant App. Например, протестировать, насколько корректно перенесутся данные пользователя. Сделать это можно двумя способами:

  1. запустить приложение с помощью специальной утилиты из Android SDK;
  2. выложить его в консоль для внутреннего тестирования и запустить через Play Market.

Первый способ достаточно удобен. Утилита входит в Android SDK, но по умолчанию не установлена. Для установки в Android Studio нужно выполнить следующие шаги:

  1. зайти в Preferences -> Appearance & Behavior -> System Settings -> Android SDK;
  2. выбрать вкладку SDK Tools;
  3. поставить галочку возле Google Play Instant Development SDK и нажать Apply.


На последнем шаге обратите внимание на директорию, в которую будет установлена утилита. Далее относительно этого пути нас будет интересовать файл ./extras/google/instantapps/ia. С его помощью можно сымитировать мгновенный запуск приложения, выполнив команду

ia run <путь к APK-файлу, bundle-у или URL>

До момента, как я наткнулся на эту утилиту, я использовал второй способ, с постоянной публикацией приложения в Google Play Console. Но так как опубликованное приложение появляется в магазине не сразу, а по истечении неопределённого времени (у меня это занимало от получаса до суток), такой способ тестирования никуда не годился. Впрочем, он для этого и не предназначен. Кстати, если вы публикуете Instant App в Google Play Console с большой частотой, советую предусмотреть возможность после запуска определить код версии приложения. Иначе бывает сложно понять, запустилась последняя опубликованная версия или предыдущая.

Публикация

Наконец, когда ваше приложение протестировано и готово к публикации, не спешите расслабляться! Во-первых, код версии (versionCode) Instant App не должен превышать код версии устанавливаемого приложения. Рекомендую заранее дать простор для творчества: указать при релизе основного приложения заведомо большое значение кода, чтобы не связывать себе руки. Удалить выпущенный Instant App из консоли с целью «высвободить» код версии для другой сборки не получится. Формально у вас имеется N-M возможностей зарелизить Instant App, пока у вас в Google Play основное приложение с versionCode = N и приложение с мгновенным запуском с versionCode = M.

Иными словами, каждый пользователь Instant App должен иметь возможность установить основное приложение. Также для релиза Instant App убедитесь, что оно будет доступно не большей аудитории, чем основное приложение.

Скажем, если ваше основное приложение требует разрешение на определение геопозиции, а в Instant App это не нужно, всё равно нужно его указать и там, и там. На аудиторию в первую очередь влияют разрешения приложения, указываемые в Manifest-файле (permissions), — они должны быть одинаковыми для обоих приложений (за исключением разрешений, не влияющих на аудиторию).

Так было и в нашем случае. Также некоторые вспомогательные библиотеки могут сузить круг конечных пользователей. В поисках решения я наткнулся на этот вопрос со Stack Overflow, где советуют прогнать APK файлы приложений через утилиту aapt. Консоль выдавала ошибку «targeting apk difference», хотя разрешения обоих приложений были одинаковыми. Вычислив разницу в выдаче по обоим файлам, я заметил зацепку: у устанавливаемого приложения была строка uses-gl-es: '0x20000', которая отсутствовала в Instant App. Она выведет подробную информацию о файлах, включая все зависимости. И действительно, наше основное приложение использовало библиотеку play-services-maps, а Instant App — нет. Недолгий сёрфинг по сети привёл меня к разгадке: эта строка говорит, что приложение использует библиотеку OpenGL, которая, в свою очередь, используется в картах. Добавление этой зависимости в Instant App позволило мне в конце концов зарелизить приложение.

Подытожим

  1. В Instant Apps нельзя использовать сервисы и незащищённые сети (http). Размер конечного APK-файла не должен превышать 4 МБ (возможно, скоро это ограничение упростят до 10 МБ).
  2. Для уменьшения размера APK-файла можно применять оптимизаторы и обфускаторы кода (например, ProGuard).
  3. Перенос SharedPreferences из Instant App в основное приложение происходит автоматически для Android 8.0+, для более ранних версий необходимо писать вручную через Cookie API или Storage API. Стоит учесть необходимость релиза подготовленного к миграции данных устанавливаемого приложения перед релизом Instant App.
  4. Для отладки Instant App можно воспользоваться специальной утилитой из Google Play Instant Development SDK, входящего в Android SDK.
  5. Появление опубликованного в консоли Instant App на конечных устройствах может происходить с задержкой от получаса до суток. Стоит позаботиться о возможности однозначно определить, какая версия Instant App сейчас запустилась из Play Market.
  6. Код версии Instant App не должен превышать код версии основного приложения.
  7. Список устройств, которым будет доступен Instant App, не должен превышать список устройств, которым доступно основное приложение. Для этого следует указывать в Manifest-файлах одинаковые разрешения, а также обратить внимание на возможные ограничения из-за вспомогательных библиотек.

На этом всё. Надеюсь, эта информация окажется для вас полезной. Буду рад любой обратной связи!

Полезные источники:

  1. Документация по Google Play Instant на Android Developers
  2. Советы по уменьшению размера APK-файла Instant App
  3. FAQ по Google Play Instant
  4. Миграция данных с помощью Cookie API
  5. Миграция данных с помощью Storage API
Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»