
Недавно наткнулся на новость о том, что количество приложений в Google Play Store сократилось на 47%.
Я сам энтузиаст разработки под Android и последние 5 лет работал над альтернативой для Google Play Music и Podcast под названием MusicSync. Так что, будучи близким к теме человеком, мне захотелось поделиться своим опытом обслуживания приложений и заодно пояснить, почему меня эта новость нисколько не удивила.
У меня есть несколько сторонних проектов, базирующихся на бэкенд-сервере с ограниченным веб-интерфейсом, и их обслуживание требует намного меньше усилий.
Если же говорить о приложении Android, то обслуживать его в качестве хобби-проекта гораздо хлопотнее. Вот некоторые из проблем, с которыми мне приходилось сталкиваться:
Java vs Kotlin
Если вы начинаете разработку под Android в 2025, то Kotlin явно станет предпочтительным языком. Но что, если вы обслуживаете хобби-проект, написанный на Java? В этом случае вы столкнётесь с проблемами несовместимости, когда обнаружите, что ваши зависимости переписывают на Kotlin.
Если ваш код зависит от библиотеки, использующей корутины Kotlin или опирающейся на suspend-функции, то вам придётся искать обходной путь или переписывать своё приложение на Kotlin.
Функциональность Jetpack Compose, официальной библиотеки Google UI для Android, из Java абсолютно недоступна.
Могу представить, что вы начали разработку на Kotlin, затем столкнулись с кучей вопросов на StackOverflow, написанных для аудитории Java, и были вынуждены переводить их в равнозначный код Kotlin.
Google вносит в свои библиотеки критические изменения
Компания Google славится своей привычкой вносить в библиотеки Android критические изменения. Ниже я перечислил некоторые библиотеки, которые я использовал в своём приложении, и проблемы, с которыми столкнулся.
Media 3
Android поставляется с MediaPlayer.
Google рекомендует использовать их опенсорсную библиотеку ExoPlayer.
ExoPlayer V1 была выпущена в 2017.
Затем её сменила не имеющая обратной совместимости ExoPlayer V2, последняя версия которой вышла в июле 2024.
А теперь и её заменили media3, также без обратной совместимости.
Скрипт перехода, который предоставили в Google, далеко не полноценный.
Пуще того, media3 не следует принципам семантического версионирования — обновление младших версий вело к критическим изменениям API.
Библиотека Google Auth
В библиотеке Google Auth был обнаружен баг, плюс в течение нескольких месяцев для API 26 и старше не работала авторизация.
java.lang.NoSuchMethodError: No virtual method getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;
in class Lsun/misc/Unsafe; or its super classes
(declaration of 'sun.misc.Unsafe' appears in /system/framework/core-libart.jar)
E at com.google.common.util.concurrent.AbstractFuture$UnsafeAtomicHelper.gasWaiters(AbstractFuture.java:1394)
E at com.google.common.util.concurrent.AbstractFuture.releaseWaiters(AbstractFuture.java:1110)
E at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1000)
E at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:783)
E at com.google.auth.oauth2.OAuth2Credentials$RefreshTask.access$400(OAuth2Credentials.java:600)
E at com.google.auth.oauth2.OAuth2Credentials$RefreshTask$1.onSuccess(OAuth2Credentials.java:617)
...
Прекращение поддержки старых версий Android
Google Ads library v24 перестала поддерживать Android API 21. Согласно официальной статистике Google, этот API использует около 0,1% (~4 миллиона) пользователей. Никаких разумных обоснований своему решению компания не привела.
Обновление ради обновления
На смену Material 2 пришёл Material 3. При этом никакого отчётливого руководства по переходу представлено не было. Почему? Для меня это загадка, которую я так и не смог разгадать. Вот какой толк от того, что основная часть документации теперь ссылается на Jetpack Compose, использовать который я не могу!?
Так что на ближайшее будущее кодовая база Java обречена использовать Material 2.
Руководства по UI-дизайну для Android развиваются непредсказуемо
Нижняя панель навигации, характерная для приложений iOS, поначалу многими воспринималась в штыки, но в итоге стала стандартной фичей в Material design.
Кнопки «вверх» и «назад» раньше могли вызывать расходящиеся действия, а теперь работают одинаково. Узнал я об этом лишь год назад, когда написал по этой теме пост на Reddit.
Некоторые могут решить, что достаточно просто использовать компоненты Material Design. Но переход с одной версии Material Design на другую тоже не так прост. И только вы перейдёте с Material 1 на Material 2, как Google уже выпускает Material 3, оставив прежние версии не у дел.
Google вносит в платформу Android критические изменения
Релиз каждой старшей версии Android несёт в себе критические изменения, создающие для разработчиков серьёзные хлопоты.
Раньше функция toast (всплывающие уведомления) работал в любом режиме приложения, а теперь, начиная с API 31, работает, только если оно находится на переднем плане. А как понять, находится ли твоё приложение на переднем плане? Нужно использовать ActivityLifecycleCallbacks и написать кучу кода, и даже в этом случае есть непонятки с onStart и onResume.
Раньше для показа уведомлений никакие разрешения были не нужны, но с выходом API 33 они стали требовать POST_NOTIFICATIONS.
Разрешения на хранение тоже либо присутствовали все, либо их не было. Теперь же, начиная с API 33, их можно тонко настраивать на уровне аудио, видео и изображений.
Ограничения фонового выполнения кода в каждом релизе постепенно корректируется.
Медиа-уведомления в API 33 заменили на обратно несовместимые. В этом длинном топике можно почитать, какую боль это создало для многих разработчиков.
Важнейшие сторонние библиотеки перестали поддерживаться
Несколько популярных сторонних библиотек были признаны устаревшими или перестали обслуживаться.
Picasso
Picasso была отличным решением для загрузки изображений, но теперь оставлена в прошлом. Её сменила coil, но обновиться на неё не так-то просто.
Glide
Glide является альтернативой Picasso, и её последняя версия была выпущена в сентябре 2023 года.
OkHttp
OkHttp, которую даже Android использует внутренне для реализации HttpURLConnection
, не получала стабильного релиза с октября 2023 года. Последней стабильной версией была 4.12.0, и даже последняя альфа вышла в апреле 2024.
OkHttp 4.12.0 не поддерживает Happy Eyeballs, что создаёт серьёзные проблемы в сетях IPv6.
EventBus
Библиотека EventBus де-факто отвечала в Android за обработку передачи событий. Сейчас её обслуживание прекращено.
RateThisApp
RateThisApp отлично справлялась с получением рейтингов приложений, но в итоге была заброшена.
И я не виню мейнтейнеров. Если вы используете опенсорсную библиотеку, то должны быть готовы к тому, что её поддержка может прекратиться. Я лишь указываю, что некоторые из шаблонных решений, которые зачастую необходимы при разработке под Android, внезапно уходят в небытие.
Две схемы версионирования
В Android используется две схемы версионирования: версия Android API для разработчиков и версия Android для маркетинга.
К примеру, Android 11 работает с API 30, Android 12 — с API 31 и 32 (!), Android 13 — это API 33, а Android 14 – API 34. В документации разработчика отсылка может идти к одной схеме или другой, а иной раз к обеим. И вам нужно учитывать все эти сочетания, занимаясь отладкой с помощью GitHub Issues или StackOverflow, что лишь привносит ненужный дискомфорт и путаницу.
Принудительные обновления
В приложении Android есть множество тесно связанных между собой версий разных элементов.
minSdkVersion
иtargetSdkVersion
приложения,Java
sourceCompatibility
иtargetCompatibility
,версии зависимостей,
версия цепочки системы сборки,
версия Gradle,
версия Android Studio.
И вы можете подумать, что все их обновления делаются по желанию, но это не так.
Gradle и Android Studio необходимо обновлять вместе, чтобы сохранить совместимость.
Обновление Java
sourceCompatibility
иtargetCompatibility
требует обновления Gradle (а значит, и Android Studio).Обновление системы сборки Android требует обновления
minSdkVersion
иtargetSdkVersion
, а также обновления Gradle.Кроме того, если вы хотите продолжать использовать старую библиотеку вроде Exoplayer V2, то рано или поздно она утратит совместимость с другими зависимостями, и вам придётся обновляться до media3.
Вот видите — вы буквально вынуждены обновлять почти всё или ничего.
А что, если вы выберете последнее? Что ж, тогда, если minSdkVersion
вашего приложения окажется слишком старой, оно будет исключено из выдачи.
Заключение
В сравнении с бэкенд-разработкой, разработка под Android требует больше усилий по части обслуживания. Поэтому, если вы планируете создать приложение под эту платформу в качестве хобби, учитывайте постоянную необходимость в его обслуживании.
Дополнение
После публикации этой статьи на главной странице Hacker News, я узнал о двух интересных вещах:
Теперь разработчики приложений, опубликованных впервые после 2021 года, должны предоставлять свои закрытые ключи подписей платформе Google Play Store.
Несколько людей предложили мне публиковать приложения на F-Droid. Но проблема в том, что эта платформа не только имеет малый охват, но и не может разруливать проблемы обратной несовместимости с базовой платформой, с заброшенными библиотеками и обратно несовместимыми изменениями в библиотеках Android.