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

Трудности обслуживания приложений под Android

Трудности обслуживания приложений под Android - 1

Недавно наткнулся на новость о том, что количество приложений в Google Play Store сократилось на 47%.

Я сам энтузиаст разработки под Android и последние 5 лет работал над альтернативой для Google Play Music и Podcast [1] под названием MusicSync [1]. Так что, будучи близким к теме человеком, мне захотелось поделиться своим опытом обслуживания приложений и заодно пояснить, почему меня эта новость нисколько не удивила.

У меня есть несколько сторонних проектов [2], базирующихся на бэкенд-сервере с ограниченным веб-интерфейсом, и их обслуживание требует намного меньше усилий.

Если же говорить о приложении Android, то обслуживать его в качестве хобби-проекта гораздо хлопотнее. Вот некоторые из проблем, с которыми мне приходилось сталкиваться:

Java vs Kotlin

Если вы начинаете разработку под Android в 2025, то Kotlin явно станет предпочтительным языком. Но что, если вы обслуживаете хобби-проект, написанный на Java? В этом случае вы столкнётесь с проблемами несовместимости, когда обнаружите, что ваши зависимости переписывают на Kotlin.

  • Если ваш код зависит от библиотеки, использующей корутины Kotlin или опирающейся на suspend-функции [3], то вам придётся искать обходной путь или переписывать своё приложение на Kotlin.

  • Функциональность Jetpack Compose, официальной библиотеки Google UI для Android, из Java абсолютно недоступна [4].

  • Могу представить, что вы начали разработку на Kotlin, затем столкнулись с кучей вопросов на StackOverflow, написанных для аудитории Java, и были вынуждены переводить их в равнозначный код Kotlin.

Google вносит в свои библиотеки критические изменения

Компания Google славится своей привычкой вносить в библиотеки Android критические изменения. Ниже я перечислил некоторые библиотеки, которые я использовал в своём приложении, и проблемы, с которыми столкнулся.

Media 3

Android поставляется с MediaPlayer [5].

Google рекомендует использовать их опенсорсную библиотеку ExoPlayer [6].

ExoPlayer V1 [7] была выпущена в 2017.

Затем её сменила не имеющая обратной совместимости ExoPlayer V2 [8], последняя версия которой вышла в июле 2024.

А теперь и её заменили media3 [9], также без обратной совместимости.

Скрипт перехода [10], который предоставили в Google, далеко не полноценный.

Пуще того, media3 не следует принципам семантического версионирования — обновление младших версий [11] вело к критическим изменениям API.

Библиотека Google Auth

В библиотеке Google Auth был обнаружен баг, плюс в течение нескольких месяцев [12] для API 26 и старше не работала авторизация [13].

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 перестала поддерживать [14] Android API 21. Согласно официальной статистике Google, этот API использует около 0,1% (~4 миллиона) [15] пользователей. Никаких разумных обоснований своему решению компания не привела.

Обновление ради обновления

На смену Material 2 пришёл Material 3. При этом никакого отчётливого руководства по переходу представлено не было. Почему? Для меня это загадка, которую я так и не смог разгадать. Вот какой толк от того, что основная часть документации теперь ссылается на Jetpack Compose, использовать который я не могу!?

Так что на ближайшее будущее кодовая база Java обречена использовать Material 2.

Руководства по UI-дизайну для Android развиваются непредсказуемо

  • Нижняя панель навигации, характерная для приложений iOS, поначалу многими воспринималась в штыки [16], но в итоге стала стандартной фичей в Material design.

  • Кнопки «вверх» и «назад» раньше могли вызывать расходящиеся действия [17], а теперь работают одинаково [18]. Узнал я об этом лишь год назад, когда написал по этой теме пост [19] на Reddit.

  • Некоторые могут решить, что достаточно просто использовать компоненты Material Design. Но переход с одной версии Material Design на другую тоже не так прост. И только вы перейдёте с Material 1 на Material 2, как Google уже выпускает Material 3, оставив прежние версии не у дел.

Google вносит в платформу Android критические изменения

Релиз каждой старшей версии Android несёт в себе критические изменения, создающие для разработчиков серьёзные хлопоты.

Важнейшие сторонние библиотеки перестали поддерживаться

Несколько популярных сторонних библиотек были признаны устаревшими или перестали обслуживаться.

Picasso

Picasso [27] была отличным решением для загрузки изображений, но теперь оставлена в прошлом [28]. Её сменила coil [29], но обновиться на неё не так-то просто.

Glide

Glide [30] является альтернативой Picasso, и её последняя версия была выпущена в сентябре 2023 года.

OkHttp

OkHttp [31], которую даже Android использует внутренне для реализации HttpURLConnection, не получала стабильного релиза с октября 2023 года. Последней стабильной версией была 4.12.0, и даже последняя альфа вышла в апреле 2024.

OkHttp 4.12.0 не поддерживает Happy Eyeballs, что создаёт серьёзные проблемы [32] в сетях IPv6.

EventBus

Библиотека EventBus [33] де-факто отвечала в Android за обработку передачи событий. Сейчас её обслуживание прекращено.

RateThisApp

RateThisApp [34] отлично справлялась с получением рейтингов приложений, но в итоге была заброшена.

И я не виню мейнтейнеров. Если вы используете опенсорсную библиотеку, то должны быть готовы к тому, что её поддержка может прекратиться. Я лишь указываю, что некоторые из шаблонных решений, которые зачастую необходимы при разработке под Android, внезапно уходят в небытие.

Две схемы версионирования

В Android используется две схемы версионирования [35]: версия 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 необходимо обновлять вместе, чтобы сохранить совместимость [36].

  • Обновление Java sourceCompatibility и targetCompatibility требует обновления Gradle (а значит, и Android Studio).

  • Обновление системы сборки Android требует обновления minSdkVersion и targetSdkVersion, а также обновления Gradle.

  • Кроме того, если вы хотите продолжать использовать старую библиотеку вроде Exoplayer V2, то рано или поздно она утратит совместимость с другими зависимостями, и вам придётся обновляться до media3.

Вот видите — вы буквально вынуждены обновлять почти всё или ничего.

А что, если вы выберете последнее? Что ж, тогда, если minSdkVersion вашего приложения окажется слишком старой, оно будет исключено из выдачи [37].

Заключение

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

Дополнение

После публикации этой статьи на главной странице Hacker News [38], я узнал о двух интересных вещах:

  • Теперь разработчики приложений, опубликованных впервые после 2021 года, должны предоставлять свои закрытые ключи подписей платформе Google Play Store.

  • Несколько людей предложили мне публиковать приложения на F-Droid. Но проблема в том, что эта платформа не только имеет малый охват, но и не может разруливать проблемы обратной несовместимости с базовой платформой, с заброшенными библиотеками и обратно несовместимыми изменениями в библиотеках Android.

Автор: Bright_Translate

Источник [39]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/java/423349

Ссылки в тексте:

[1] Google Play Music и Podcast: https://musicsync.ashishb.net/?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[2] несколько сторонних проектов: https://ashishb.net/programming/how-to-deploy-side-projects-as-web-services-for-free/

[3] suspend-функции: https://coil-kt.github.io/coil/java_compatibility/?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[4] абсолютно недоступна: https://stackoverflow.com/questions/66433437/can-i-write-jetpack-compose-components-in-java?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[5] MediaPlayer: https://developer.android.com/reference/android/media/MediaPlayer?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[6] ExoPlayer: https://github.com/google/ExoPlayer?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[7] ExoPlayer V1: https://github.com/google/ExoPlayer/tree/release-v1?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[8] ExoPlayer V2: https://github.com/google/ExoPlayer/tree/release-v2?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[9] media3: https://www.reddit.com/r/androiddev/comments/1atqkjs/is_media3_migration_worth_it/?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[10] Скрипт перехода: https://github.com/google/ExoPlayer/blob/release-v2/media3-migration.sh?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[11] обновление младших версий: https://github.com/androidx/media/issues/2278?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[12] в течение нескольких месяцев: https://gist.github.com/ashishb/108a095603446fa39eb901b006642af6?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[13] не работала авторизация: https://ashishb.net/programming/end-to-end-testing-mobile-apps/

[14] перестала поддерживать: https://developers.google.com/admob/android/migration#migrate-to-v24?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[15] около 0,1% (~4 миллиона): https://composables.com/android-distribution-chart?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[16] воспринималась в штыки: https://androiduipatterns.com/on-the-bottom-navigation-bar-d07d9b4b5e18?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[17] расходящиеся действия: https://web.archive.org/web/20160317020901/http://developer.android.com/design/patterns/navigation.html#up-vs-back?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[18] одинаково: https://developer.android.com/guide/navigation/principles#:~:text=If%20a%20user%20is%20at,and%20does%20exit%20the%20app?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[19] пост: https://www.reddit.com/r/androiddev/comments/1c90gft/android_navigation_up_vs_back/?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[20] только если оно находится на переднем плане: https://developer.android.com/guide/topics/ui/notifiers/toasts?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[21] ActivityLifecycleCallbacks: https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[22] onStart и onResume: https://steveliles.github.io/is_my_android_app_currently_foreground_or_background.html?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[23] POST_NOTIFICATIONS: https://developer.android.com/training/notify-user/notifications#permissions?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[24] начиная с API 33: https://developer.android.com/about/versions/13/behavior-changes-13?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[25] Ограничения фонового выполнения кода: https://developer.android.com/about/versions/oreo/background?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[26] этом длинном топике: https://github.com/androidx/media/issues/216?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[27] Picasso: https://github.com/square/picasso?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[28] оставлена в прошлом: https://www.reddit.com/r/androiddev/comments/1gk6bd9/picasso_is_formally_deprecated/?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[29] coil: https://github.com/coil-kt/coil?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[30] Glide: https://github.com/bumptech/glide?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[31] OkHttp: https://github.com/square/okhttp?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[32] серьёзные проблемы: https://github.com/square/okhttp/issues/506?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[33] EventBus: https://github.com/greenrobot/EventBus?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[34] RateThisApp: https://github.com/kobakei/Android-RateThisApp/?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[35] схемы версионирования: https://developer.android.com/tools/releases/platforms?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[36] совместимость: https://developer.android.com/studio/releases#android_gradle_plugin_and_android_studio_compatibility?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[37] исключено из выдачи: https://developer.android.com/google/play/requirements/target-sdk?utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[38] главной странице Hacker News: https://news.ycombinator.com/item?id=44214835&utm_source=https://ashishb.net&utm_medium=referral&utm_campaign=blog

[39] Источник: https://habr.com/ru/companies/ruvds/articles/919434/?utm_source=habrahabr&utm_medium=rss&utm_campaign=919434