- PVSM.RU - https://www.pvsm.ru -

Привет! Меня зовут Камо Сперцян, я занимаюсь Android-разработкой в PROFI.RU. Недавно я написал приложение с мгновенным запуском для наших клиентов. Если вы ещё не знакомы с технологией, приглашаю вас сначала посетить Android Developers [1].
С презентации 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 от этой фичи отказались, мотивируя пользователей скачать основное приложение. Но этот момент стоит учитывать, если ваше приложение тоже использует сервисы.
К моему удивлению, полученное копированием только нужных кусков кода приложение всё равно не влезло в допустимые 4 МБ и весило около 5 МБ. В этой статье [2] Google даёт советы на этот случай, но мне они мало помогли. Единственное, от чего мы могли отказаться, — кастомные шрифты, но их вес существенно не влиял на размер APK.
Тут я вспомнил, что ProGuard у нас в проекте отключён на debug-сборках. Простое включение
minifyEnabled true
сократило размер приложения чуть ли не вдвое. О чудо — ограничение в 4 МБ соблюдено!
Далее предстояло решить вопрос с миграцией данных. Как известно, Instant Apps поддерживаются операционной системой Android с версии 5.0. При этом автоматическая миграция данных работает только начиная с Android 8.0. Для этого достаточно использовать в обоих приложениях файлы shared preferences с одинаковым названием. Для версий с 5.0 по 7.1 миграцию нужно писать вручную с помощью Cookie API [3] или Storage API [4]. Я воспользовался Cookie и с особыми проблемами не столкнулся — правда, это потребовало изменений не только на стороне Instant App, но и в устанавливаемом приложении. Так что в итоге пришлось выпустить новую версию приложения и раскатить её на всю аудиторию для релиза Instant App.
С отладкой всё оказалось не так просто.
Во-первых, Google Play Instant не поддерживает незащищённые сетевые соединения, так что забудьте про http, только https. Для меня это означало тестирование на production-серверах, так как все тестовые стенды работали по http. Не критично, но приятного мало.
Во-вторых, сам запуск Instant App: вы можете тестировать приложение как обычное, устанавливаемое, но лишь до поры до времени. При запусках через Android Studio невозможно проверить обновление Instant App до «полноценного» приложения. Например, протестировать, насколько корректно перенесутся данные пользователя. Для этого нужно запускать приложение с мгновенным запуском именно как Instant App. Сделать это можно двумя способами:
Первый способ достаточно удобен. Утилита входит в Android SDK, но по умолчанию не установлена. Для установки в Android Studio нужно выполнить следующие шаги:

На последнем шаге обратите внимание на директорию, в которую будет установлена утилита. Далее относительно этого пути нас будет интересовать файл ./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 должен иметь возможность установить основное приложение.
На аудиторию в первую очередь влияют разрешения приложения, указываемые в Manifest-файле (permissions), — они должны быть одинаковыми для обоих приложений (за исключением разрешений, не влияющих на аудиторию). Скажем, если ваше основное приложение требует разрешение на определение геопозиции, а в Instant App это не нужно, всё равно нужно его указать и там, и там.
Также некоторые вспомогательные библиотеки могут сузить круг конечных пользователей. Так было и в нашем случае. Консоль выдавала ошибку «targeting apk difference», хотя разрешения обоих приложений были одинаковыми. В поисках решения я наткнулся на этот вопрос [5] со Stack Overflow, где советуют прогнать APK файлы приложений через утилиту aapt. Она выведет подробную информацию о файлах, включая все зависимости. Вычислив разницу в выдаче по обоим файлам, я заметил зацепку: у устанавливаемого приложения была строка uses-gl-es: '0x20000', которая отсутствовала в Instant App. Недолгий сёрфинг по сети привёл меня к разгадке: эта строка говорит, что приложение использует библиотеку OpenGL, которая, в свою очередь, используется в картах. И действительно, наше основное приложение использовало библиотеку play-services-maps, а Instant App — нет. Добавление этой зависимости в Instant App позволило мне в конце концов зарелизить приложение.
На этом всё. Надеюсь, эта информация окажется для вас полезной. Буду рад любой обратной связи!
Автор: sc_pro_ion
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android/305874
Ссылки в тексте:
[1] Android Developers: https://developer.android.com/topic/google-play-instant/
[2] этой статье: https://developer.android.com/topic/google-play-instant/guides/reduce-module-size
[3] Cookie API: https://github.com/googlesamples/android-instant-apps/tree/master/cookie-api
[4] Storage API: https://github.com/googlesamples/android-instant-apps/tree/master/storage-api
[5] этот вопрос: https://stackoverflow.com/questions/45975231/google-play-console-error-non-upgradable-to-installed-app
[6] FAQ по Google Play Instant: https://developer.android.com/topic/google-play-instant/faqs
[7] Источник: https://habr.com/ru/post/436780/?utm_campaign=436780
Нажмите здесь для печати.