Міграція Android-додатку з Java на Kotlin

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Міграція Android-додатку з Java на Kotlin
Складний
від 2 тижнів до 3 місяців
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Міграція Android-застосунку з Java на Kotlin

У репозиторії 80 000 строк Java-коду, команда давно знає всі грабли, продукт працює — та тут Google оголошує, що нові Jetpack API розробляються тільки для Kotlin, а частина існуючих отримує Kotlin-first surface. Paging 3, DataStore, WorkManager з корутинами, Jetpack Compose — все це технічно доступно з Java, але з такими адаптерами та обходними шляхами, що розробка перетворюється в боротьбу з інструментами замість вирішення задач.

Міграція з Java на Kotlin — не переписування з нуля. Це поступовий процес, який при правильній організації не зупиняє розробку продукту та не ломає стабільність.

Чому не можна просто натиснути «Convert Java File to Kotlin»

Android Studio вміє конвертувати Java-файли в Kotlin автоматично. Результат — технічно компілюється. Але це не Kotlin, це транслітерація Java на синтаксис Kotlin:

  • var всюди замість val — немає immutability
  • !! на кожній null-ссилці — NullPointerException просто переименований на KotlinNullPointerException
  • Немає data classes — ті ж POJO з геттерами через field.get()
  • object та companion objects відсутні — static-методи болтаються як extensions
  • Coroutines нема — залишається AsyncTask або RxJava
  • Лямбди виглядають як Java 8 лямбди, але без SAM conversion для користувальницьких інтерфейсів

Такий код не дає ніяких переваг Kotlin, тільки додає путаницю. Автоконвертер — інструмент для початку, не для фіналу.

Як виглядає правильна міграція

Інвентаризація перед стартом

Перший крок — повний аудит кодової бази: кількість класів по типах (Activity, Fragment, ViewModel, Repository, Model, Util), покриття тестами, список активно розробляємих модулів vs стабільних, залежності від Kotlin-несумісних паттернів (наприклад, finalize(), певні паттерни з static inner classes).

На основі аудиту будується план: які файли конвертуємо в першу чергу, які трогаємо в останню, де паралельна розробка на Java йде під час міграції.

Стратегія «знизу вверх»

Починаємо з класів без Android-залежностей: моделі даних, утиліти, константи. Java POJO з полями, геттерами та сеттерами перетворюється на Kotlin data class — це миттєва виигра: equals(), hashCode(), toString(), copy() безплатно.

// Було: Java POJO, 60 строк з геттерами/сеттерами
// Стало:
data class UserProfile(
    val id: Long,
    val name: String,
    val email: String,
    val avatarUrl: String? = null
)

Потім переходимо до Repository-шару. Тут ключове рішення — як обращаться з async-кодом. Якщо в проекті був RxJava, можливі два шляхи: залишити RxJava (Kotlin з RxJava працює чудово) або мігрувати на coroutines + Flow. Другий шлях стратегічно правильніший, але дорожче в моменте. Для активно розробляємих репозиторіїв робимо coroutines; для стабільних модулів без змін — залишаємо RxJava до наступного великого рефакторингу.

ViewModel-шар: LiveDataStateFlow + SharedFlow. Це не обов'язковий крок, LiveData працює й у Kotlin, але StateFlow ведёт себя передбачуваніше — нема магії з LifecycleOwner, нема observeForever утечок, нема setValue vs postValue путаниці.

Activity та Fragment мігруємо останніми. Там більше всього залежностей, більше всього legacy-коду, та помилки там дорожче всього.

Робота з Java-Kotlin interop

Поки міграція не завершена, Java та Kotlin класи живут рядом. Kotlin вибивает Java без проблем. Java вибивает Kotlin — потрібні аннотації:

  • @JvmStatic для companion object методів, які потрібні з Java
  • @JvmField для полів без геттерів
  • @JvmOverloads для функцій з default parameters
  • @Throws(IOException::class) якщо Kotlin-функція видає checked exceptions

Ігнорування цих аннотацій — частая причина того, що автоконвертований код не компілюється з сусідніх Java-файлів.

Тестування в процесі міграції

Кожен конвертований клас повинен проходити існуючі тесты без змін — це гарантія, що конвертація не сломала логіку. Якщо тестів не було — це момент їх написати, до конвертації, поки логіка зрозуміла з Java-коду. Використовуємо JUnit5 + MockK (для Kotlin-класів) або Mockito (якщо потрібна сумісність з Java-тестами).

CI повинен гонити тесты на кожен PR. Міграція без CI — це хаос: неможливо відстежити, який саме коміт сломав логіку.

Що ще змінюється попутно

При міграції розумно попутно вирішувати накопичений технічний борг: замінити AsyncTask (deprecated з API 30) на coroutines, перейти з SharedPreferences на DataStore, оновити Retrofit до версії з Kotlin suspend-функціями замість Call<T>.

Але «попутно» не означає «всё одразу». Кожне таке змінення — ризик регресії. Складаємо явний список «що робимо в рамках міграції», все інше — в backlog наступних спринтів.

Строки

Залежать від обсягу кодової бази, покриття тестами та того, йде ли паралельна розробка нових фіч.

Кодова база Покриття тестами Оцінка
до 20 000 строк Java добре (>60%) 2–4 тижні
20 000 – 60 000 строк часткове 4–8 тижнів
60 000+ строк низьке 2–4 місяці

Оцінка уточняється після аудиту. Вартість розраховується індивідуально.

Міграція — інвестиція. Команда, яка працює на Kotlin з coroutines та StateFlow, закриває задачі швидше, ніж та сама команда на Java з RxJava. Не тому що Kotlin магічно краще, а тому що менше бойлерплейту, кращі інструменти аналізу (KSP vs KAPT, lint-правила Kotlin), та бібліотечна екосистема більше не опирається.