HuTor Tech logo HuTor Tech
← All posts

· hutor.tech

How to move an Android app from Java to Kotlin

How to move an Android app from Java to Kotlin

Kotlin and Java live in the same project without any trouble, which is the single most useful fact about this migration: it does not have to happen at once, and it does not have to happen everywhere. An app can ship after every step, and that is what makes the work safe.

Set the ground first. A recent Android Gradle Plugin, the Kotlin plugin in the build files, and a green build on the machine that assembles releases — not only on a laptop. If the project has no tests at all, add a handful around whatever decides money or data before touching the code; you will lean on them for the whole migration.

Then convert in an order that keeps the risk low:
— start with data classes and small utilities, where the conversion is mechanical and the diff is easy to read;
— then repositories and the network layer;
— then view models and presenters;
— leave the screens and anything touching the framework's lifecycle for last.

Android Studio's “Convert Java File to Kotlin File” does the mechanical part, but never trust its output as final. It marks every type coming from Java as a platform type, which quietly turns off exactly the null safety you came for. Go through the converted file and decide, field by field, what is really nullable — then say so in the type. That single pass is where most of the value of this migration lives.

A few things the converter gets syntactically right and semantically wrong: `lateinit` sprinkled over fields that would be better as constructor parameters, nullable types everywhere “just in case”, `!!` where a proper check belongs, and companion objects standing in for what were static helpers and could now be top-level functions.

Once a layer is in Kotlin, use what the language gives you rather than writing Java in Kotlin syntax: coroutines instead of callback chains and `AsyncTask`, data classes instead of hand-written `equals`, sealed classes for screen state, extension functions instead of a `Utils` bag of static methods.

Keep two rules to the end. Every commit leaves the app buildable and releasable — no half-converted branches living for weeks. And a mixed project is a perfectly good end state: if a Java module is stable, well understood and rarely touched, converting it buys nothing but risk. The point of the migration is safer code where it is being changed, not a green Kotlin badge on the repository.