For many years, Java has been the main language for Android development. However, today, Kotlin is the default choice for new projects, and many older projects migrate to this modern language as well. At this point, most Android developers wouldn’t even consider Java as a viable language for a new project, but I did start a new Java Android app in 2022.
In this article, I’ll explain the reasons why I chose Java for this very important and challenging project, and describe how it played out over the course of one year of active development.
Why I Chose Java in 2022
The short answer is that I knew that build times will be of paramount importance for this application, and in this context Kotlin loses to Java big time.
Build times are an important metric for all Android projects, but, in this case, I knew that quick builds should be my top priority because the project involved a lot of custom drawings on a canvas. Furthermore, this application targeted a special type of Android devices that use a new screen technology, and I was pretty sure that this will be the first commercial third-party app written for that platform. So, I anticipated a lot of integration challenges around canvas manipulations, which would require hundreds of app rebuilds per day. Given extremely short and ambitious timelines, I had to achieve top productivity and velocity.
To assess the impact of Kotlin on build times, I performed profiling of several Android projects of comparable sizes and complexity. Luckily, back then, I had had source code for two applications belonging to the same company which were written using a similar set of tools and architectural approaches. The first app was purely in Java while the second app was mostly in Kotlin with some Java additions. Since these applications were very similar from technical standpoint and targeted the same business domain, I basically had an ideal test case for comparing Java and Kotlin.
These are the line counts of the three apps that I benchmarked:
And these are the build time results:
I totally expected Kotlin’s build times to be longer, but the size of the effect caught me by surprise: for some common code changes, Kotlin codebase would require x3 time to be rebuilt incrementally. This was no-go for this project, and that’s why I went ahead with Java.
The State of Our Java Android Application in 2023
Now let’s review the state of this Android application after one year of development. In fact, today we have two applications because we do not use Google Play as a distribution channel. Instead, we built our own Mobile Device Management (MDM) solution which is preinstalled on our devices and handles the installation and updates of the main app.
Let’s start with the basic lines of code metric. Across our two applications, we accumulated approximately 100,000 lines of code:
Most Android applications never get to this size, definitely not in one year.
The choice of Java for this project paid off immensely: incremental re-builds of debug variant of our main application take just about 10 seconds on my machine. This enables very short iteration cycles and spares a lot of time. Such short build time is especially impressive given the fact that more than 95% of our main app’s source code resides in a single module. We do have three additional Gradle modules in the project which are used to decouple specific parts of the codebase, but, over the last year, we invested zero effort in optimizing build times using modularization. So, we got quick build times basically for free.
Aside from the share amount of code in our apps, we also built very complex features. Our main application implements full offline mode and can work without internet connection, has a lot of complex logic to support custom drawings on a new type of Android devices, required extensive performance profiling and optimizations, implements very tricky user interface patterns, integrates with data-rich external third-party services and more. On top of that, we have our MDM application, that I already mentioned, which is also a major challenge all by itself.
All in all, during past year, we built a very complex system. Amazingly, I can’t remember struggling with any Java-related issues during this time: no versions mismatches, no figuring out conflicting dependencies, no cryptic errors, nothing. All these hoops that I have to jump through in Kotlin projects simply don’t exist in Java world. Instead, everything just works. I don’t remember ever invalidating caches and/or restarting Android Studio on this project, and Android Studio is also more responsive with Java and its code completion is quicker and much more accurate. All these benefits allowed us to concentrate on creating business value in a very challenging environment, instead of spending time on figuring out the tooling and inter-dependencies.
Most of my clients are either actively migrating their Android projects to Kotlin, or already have 100% Kotlin codebases. The most common explanation for this migration that I hear from managers and CTOs is that they’re afraid that sticking with Java codebase will make it harder to attract good talent. The general assumption seems to be that good Android developers don’t want to work with Java.
To be frank, I think this argument has its merit, especially for bigger projects that need more than several developers. At even bigger companies, that employ tens or hundreds of Android devs, the attractiveness of the tech stack should be taken very seriously.
However, our application was developed by just two developers. In fact, even this is a bit of an overstatement because I dedicated less than 50% of my time to it. So, it was me leading the project and another freelance developer with about two years of experience that I hired. Yes, I’m dead serious – this extremely complex system was developed by just two developers, one of which worked part-time. And we didn’t just opt for the quick and dirty approach. No, no. We invested the time into building a solid foundation and also carried out multiple refactoring to pay for the tech debt along the way. For example, we used Parse Local Datastore as our offline storage mechanism to speed up the release of the first production version of the system, and then, later, refactored this major piece of logic to Room to have access to ACID transactions in order to improve system’s reliability.
Undoubtedly, the architectural decisions that we made along the way played the most important role in allowing us to pull this feat off with such small team. However, Java was instrumental in this context as well because it made us extremely productive and effective with our time.
In terms of hiring, I’ve got an interesting anecdote to tell you. I had known that I’ll need assistance with this project, so I interviewed several very experienced developers, all of whom had more than five years of professional experience. I also interviewed one young developer who caught my eye, with just two years of experience. Eventually, I hired the younger developer, and he turned out to be my best hire ever. Why I decided to hire him instead of the much more experienced candidates for this very complex project? Because when I asked “do you mind working in Java?”, he responded: “I know Kotlin much better than Java, but I try not to get emotionally attached to programming languages, which are just tools”. That was pure music for my ears and, for what it’s worth, I consider this mindset to be the mark of a true professional.
Clearly, Java is on the downward trend in Android ecosystem and very few developers would be enthusiastic about using it instead of Kotlin. However, in my opinion, behind all the hype and Google’s PR efforts hides a simple truth: from purely technical standpoint, Java is still the better choice for serious and complex Android projects.
During the past year, in addition to the Java project that I described here, I was also involved in three other projects. Two of them were pure Kotlin projects and one was a mixed Java-Kotlin codebase. The difference in development experience between our project and those other projects was just staggering. Now, I do like some of Kotlin’s bells and whistles, but they are nowhere close to compensate for the loss of stability and productivity compared to Java.
Don’t get me wrong, though: I’m not holding my breath to see Java renaissance in Android. This won’t happen. However, as the ecosystem is migrating to Kotlin, Jetpack Compose and co., there is a lot of opportunity for professional devs to give their projects a competitive edge and spare their employers a lot of money.