Why we moved to Kotlin for Android development (and maybe you should too)

published in Android Development
by Jakub Chmiel

Recently Kotlin programming is really endorsed by Google and most of the developers. We are not an exception. We moved to Kotlin for Android development and it was worth it. Here are 8 reasons why we did it.

1. Boilerplate code

Kotlin introduced Data Classes and many other features that reduce boilerplate code. For example copy() function that copies an object with the possibility to easily modify its state. This function saves a lot of space and you can use it on immutable values.

Here are a simple Data Class ‘Developer’ and ‘developerJohn’ that want to copy- changing only Developer’s name.

data class Developer(val firstName: String?, val lastName: String?, val age: Int?)
val developerJohn = Developer("John", "Kotlin", 10)
val twinDeveloperMark = developerJohn.copy("Mark")

I copied the first developer and created a twin brother with a different name but the same last name and age. As you can see, you can simply change one value even in an immutable object. It would be a chore to duplicate a bigger object manually only to change one value.

Java is getting better with each version but still forces a lot of boilerplate code. It offers ‘clone’ function but usually, it doesn’t work properly and developers advise to avoid it. So in Java, it would look like below.

class Developer {
   private String firstName;
   private String lastName;
   private int age;

   Developer(String firstName, String lastName, int age) {
       this.firstName = firstName;
       this.lastName = lastName;
       this.age = age;
   }

   public String getFirstName() {
       return firstName;
   }

   public void setFirstName(String firstName) {
       this.firstName = firstName;
   }

   public String getLastName() {
       return lastName;
   }

   public void setLastName(String lastName) {
       this.lastName = lastName;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

}
Developer developerJohn = new Developer("John", "Kotlin", 10);
Developer twinDeveloperMark = new Developer("Mark", "Kotlin", 10);

‘Developer’ is fortunately a small model. Copying much bigger models manually is really annoying and space-wasting.

2. Null safety

Kotlin gives a smaller probability of app crashes because it’s easy to deal with NullPointerException. That’s where many operators come in handy.  For example:


data class Developer(val firstName: String?)

fun handleDeveloper(developer: Developer?) {

developer?.firstName // get firstName if developer is not null
developer!!.firstName // get firstName even if developer is null -> may lead to crashes
developer?.let { // let me operate on developer in a block of code if developer is not null
 	  it.firstName
}
}

Java 8 introduced Optional but it’s still harder to deal with NullPointerExceptions. Also, in Android development Java Optional is fully available only for Android 7.0+.

Kotlin for Android development

Trying to use Optionals when minimum API is below level 24

3. Flexibility

Kotlin is very flexible thanks to Extension Functions. If a class doesn’t have a useful function that would make your code fluid and readable- you can create this function yourself. For example, if you want to create a function that returns initials of the full name ->

fun Developer.getInitials(): String {
   val firstNameInitial = firstName?.firstOrNull()?.toUpperCase()
   val lastNameInitial = lastName?.firstOrNull()?.toUpperCase()
   if(firstNameInitial == null || lastNameInitial == null) {
       return "N/A"
   }

   return "$firstNameInitial$lastNameInitial"
}

By the way ‘firstOrNull()’ is an extension function too.

Java doesn’t provide Extension Functions, you are limited by methods that exist in a class or you have to override it. You can use regular static methods but it’s a less readable solution. If you want to do the same in Java, look below:

static String getInitials(Developer developer) {
   Character firstNameInitial = null;
   if (developer.getFirstName() != null) {
       firstNameInitial = developer.getFirstName().toUpperCase().charAt(0);
   }

   Character lastNameInitial = null;
   if (developer.getLastName() != null) {
       lastNameInitial = developer.getLastName().toUpperCase().charAt(0);
   }

   if(firstNameInitial == null || lastNameInitial == null) {
       return "N/A";
   }

   return firstNameInitial.toString() + lastNameInitial.toString();
}

4. Accessing views

Kotlin provides AndroidX synthetic imports. That’s why, in Activities, you can directly access Views using their ids assigned in XML. You don’t have to create new variables for them. That’s how it works:

developer_name.text = “John”

On the other hand, Java requires the use of findViewById which generates a lot of boilerplate.

developerName = (TextView) findViewById(R.id.developer_name);
developerName.setText(“John”)

Of course, you can use 3rd party libraries like Butterknife but it’s still a mess.

@BindView(R.id.developer_name) TextView developerName;
developerName.setText(“John”)

5. Defining types

In Kotlin you don’t have to define types because it’s optional. Usually, it’s redundant. The ‘val’ and ‘var’ operators take a while to get used to but are really rewarding.

val name = "John"
var age = 10

Java requires defining types and it makes your code less readable.

 final String name = “John”
Int age = 10

6. Scope Functions

Kotlin provides scope functions, like ’run’, 'with', 'let',‘also’ and 'apply', which execute a block of code within the context of an object.

Let’s say you want to do multiple operations on the same object. You don’t have to access it, again and again, every time. Declare that you want to work in a given scope using the Scope Functions and your life will be easier.

‘run’,‘with’ and ‘let’ return the lambda result whereas ‘also’ and ‘apply’ return the context object.

popupMenu.run {
   menuItemVisibility(R.id.action_close, canViewActionClose)
   menuItemVisibility(R.id.action_open, canViewActionOpen)
   menuItemVisibility(R.id.action_done, canViewActionDone)
   menuItemVisibility(R.id.action_reject, canViewActionReject)
}

My favorite Scope Function is ‘let’ because it works perfectly with null safety.

menu.findItem(R.id.action_download)?.let { action ->
   if (isActionDownloadAvailable) action.show() else action.hide()
}

If there is no action_download menu item, the block of code won’t execute. ‘Action’ inside the block of code is not non-nullable.

When it comes to Java- it doesn’t provide scope functions. You have to show context (popupMenu) every time.

popupMenu.setMenuItemVisibility(R.id.action_close, canViewActionClose)
popupMenu.setMenuItemVisibility(R.id.action_open, canViewActionOpen)
popupMenu.setMenuItemVisibility(R.id.action_done, canViewActionDone)
popupMenu.setMenuItemVisibility(R.id.action_reject, canViewActionReject)

7. Switch statements

Kotlin offers 'when' statements- 'switches on steroids'. Also, Kotlin introduced sealed classes that are very useful for when statements. They can autofill all possible cases automatically (alt+enter driven development magic) and skip 'else' a statement.

That’s how the Sealed Class implementation looks like:

sealed class FileResourceDownloadResult

data class DownloadResultSuccess(
   val file: File,
   val statusCode: StatusCode
) : FileResourceDownloadResult()

data class DownloadResultError(
   val statusCode: StatusCode,
   val throwable: Throwable
) : FileResourceDownloadResult()

For now, it may seem that there is nothing special. But here comes my favorite feature since 800 BC ->

return when (result) {
   is DownloadResultSuccess -> Result.success()
   is DownloadResultError -> Result.failure()
}

Notice that there is no else or default branch. You can return a non-nullable result and you don’t have to handle a redundant ‘else’ case. I hate this additional case because usually, it generates a lot of mess. Look at what you get when you want to do the same without the Sealed Class:

return when (result) {
   is DownloadResultSuccess -> Result.success()
   is DownloadResultError -> Result.failure()
   else -> {
       // error- you have to provide the else statement
   }
}

Let’s get back to Java. It provides 'switch' statements but they always require a default value too. Even if you handle all possible cases exclusively. That’s because Java doesn’t support sealed classes.

8. Official Android language

For a long time, Java was a standard language for Android development. It has changed two years ago when JetBrains introduced Kotlin. It quickly took over the Android development world.

By then, for a long time, Kotlin was preferred and promoted by many experienced developers but nobody considered this language as the first-class citizen. But recently Google officially announced that Kotlin is now a preferred language for Android development. Of course, Android still supports Java. But in the “Fragmented”, the biggest Android Dev podcast, Google engineers endorsed moving to Kotlin and explained that new code guidelines will be mostly tailored for this language. Fortunately, now it’s really easy to migrate to Kotlin.

Kotlin for Android development

Converting Java file to Kotlin file

Why we moved to Kotlin for Android development – summary

There are new and better features provided with each Java version. The problem is they are not popular in Android development. Some of them require Java 1.8 that is fully available only for Android 7.0+. The rest of them can’t be done in Java. But Kotlin has all great features organized and provided by default. So in 2019 Kotlin for Android development is a way to go.

Also, Kotlin has well-organized documentation that’s easy to read. You can find it here.

Check our other article connected with Android development.

Jakub Chmiel Mobile Developer

Jakub is a mobile developer at Zaven. He writes about Android development here and on his own blog too!

Popular posts

Clutch Announces Zaven as Top Polish Development in  2019 Eastern European Leaders Award

Clutch Announces Zaven as Top Polish Development in 2019 Eastern European Leaders Award

Since 2011, Zaven has been providing digital solutions for global clients. Our team is composed of experts in custom development, UX/UI design, data analytics, backend integration and more. We aim to build long-term business relationships with our clients in order to create the highest quality and most innovative solutions. Clutch, a B2B market research platform, […]

Read more
How to overcame the fear of hiring outsourced developers?

How to overcame the fear of hiring outsourced developers?

There is many a legend about outsourcing which successfully keeps away entrepreneurs. Stories about software which never even existed, despite the fact that the developer had promised that everything was fine - even ahead of deadline. No communication with the developer for a long, long time and then it turns out that nobody has been working because it is Chinese New Year! These are telling examples and they are not isolated. I can only imagine the fear that grips some people when the subject of outsourcing steps out of the shadows! Let’s just deal with the most common fears of hiring outsourced developers.

Read more
How to estimate a mobile app development project?

How to estimate a mobile app development project?

Do you want to develop your own mobile app, but not know how to estimate a mobile app development project? It all depends on the features, complexity and the selected platform. The price of a small application with basic functionality ranges from €8,931 to €44,653. Read on to find out more about estimating a mobile app.

Read more
Mobile Apps

Get your mobile app in 3 easy steps!

1

Spec out

with the help of our
business analyst

2

Develop

design, implement
and test, repeat!

3

Publish

get your app out
to the stores


back to top