Get insightful engineering articles delivered directly to your inbox.
By

— 7 minute read

Five Tools Kotlin Gives Android

In the history of native Android development we’ve had several options for languages to code in. But Google historically hasn’t given us any first party support for other languages other than Java and C++. That all changed at Google IO 2017 when they announced support for Kotlin.

If you’re using the latest version of Android Studio then you’re already set up to use Kotlin. The IDE can also convert your existing Java code into Kotlin in case you want to see how a rewrite looks. And the two languages have complete interop - you can write a Kotlin class and the call it inside of Java.

Why bother with Kotlin though? If you’re an experienced Java developer on Android, why shouldn’t you keep moving right along with what you’ve used in the past? Apart from being the new and shiny, the Kotlin language also brings several new tools to the table that can make your code easier to read and faster to write. Here are my top five favorites:

#1 - Null Safety

Who doesn’t love Java Null Pointer Exceptions? If I could have a penny for every NPE that I’ve encountered in my career - I could solve global warming and buy everyone a pony with the left over money.

I’m sure you’ve encountered something like this situation in the past:

Java:

SomeCoolClass someCoolClass;
String firstValue = someCoolClass.first();
//NullPointerException

In this case I’m declaring a new SomeCoolClass instance with the intention of using it later. Then on line two I forget that it’s not instantiated. Obviously when I call first(), Java explodes because someCoolClass is null.

With the abundance of asynchronous coding and more complex architecture, these kinds of simple mistakes are really easy to make (and my mind is on global warming and buying the world ponies remember?)

Kotlin gives us a way to protect us from ourselves with Null Safety. It’s not a new concept - the idea here is that for those cases where null is a possible value we’ll stop first() from being called it if someCoolClass isn’t instantiated.

Kotlin:

var someCoolClass: SomeCoolClass? = null
var firstValue: String? = someCoolClass?.first()
//Returns null not a NPE

If you’re wondering what the whole business with the ? mark after the type declaration for firstValue is about, it’s because Strings aren’t allowed to be null in Kotlin by default. You can still allow it with the ? . In the case where someCoolClass isn’t instantiated, firstValue will be equal to null.

After I came up with the example above I thought of more realistic example of when this could happen. Let’s say you want a default value in the case where someCoolClass is null. In that case you can use the ?: operator. It functions just like a ternary operator except it handles that case where the conditional is null.

var someCoolClass: SomeCoolClass? = null
var firstValue: String = (someCoolClass?.first() ?: "My Default Value")
//Returns 'My Default Value'

someCoolClass = SomeCoolClass()
firstValue = (someCoolClass?.first() ?: "My Second Default Value")
//Returns the value of someCoolClass.first()

In this example, I can drop the ? null check for String because my value will always be either the value of first() or the default. It someCoolClass is null or if first() for some reason returns null, then the default value would be what the firstValue variable is set to.

#2 - Ranges

Ranges are something you aren’t going to use a lot, but when you do you’ll get away with writing much less code than you would in Java.

Here’s a counting loop in Java:

for (int k = 1; k < 11; k++) {
  println("Current number is " + k);
}
//Prints 1 through 10

Despite having written possibly millions of loops in my career, I sometimes still have to pause and consider the termination condition. When k < 11 and I’m incrementing by one, that means k is going to stop at 10. It’s very easy to forget and when you’re in a hurry those are the kinds of bugs that can eat away your day.

By using ranges in Kotlin, we can convert that loop back into the way our brains naturally thing about counting. You don’t say, count from 1 to the max integer less than 11, you’re saying count from 1 to 10.

for (k in 1..10) println("Current number is $k")
//Also prints 1 through 10

Decrementing using ranges is equally simple if you use the keyword downTo you can reverse the whole thing.

for (k in 10 downTo 1) println("Current number is $k")
//Prints in reverse, 10 to 1

I’ve also thrown in string templates in my example for you. Instead of concatenating a string you can drop the variable into the string with a $ that designates its position.

#3 - Extension functions

Other languages have extension functions and you can really get yourself into trouble if you aren’t careful. I still think they’re a useful tool for the language because you can reduce a lot of code by adding a function onto an existing class without extending it.

fun String.cheez() : String {
  return "$this has cheezburger?"
}
var burgered = "Josh".cheez()
println(burgered)
//Josh has cheezburger?

You could use extension functions for formatting of values that are used throughout your app.

#4- Lambda Expressions

If you want to use Lambdas in Android with Java you’ll have to switch to using Java 8 or use the Retrolambda Gradle plugin. Kotlin can make this a bit easier because you don’t have to configure anything additional once you’ve added the language to your build.gradle file.

In case you haven’t used Lambdas with Java before they allow you to reduce a fair amount of boilerplate. The most common example is adding a listener:

Java:

feedbackButton.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    presenter.showFeedback();
  }
}

Kotlin:

feedbackButton.setOnClickListener({ view -> presenter.showFeedback() })

By using a Lambda you can drop the anonymous function and since the OnClickListener only has one public method that can be overridden you can reduce it to just the argument view.

In Kotlin you can take it one step further if you aren’t using the view argument, you can reduce it all the way down to the handler internal code.

feedbackButton.setOnClickListener { presenter.showFeedback() }

People either love or hate Lambda’s, but in my opinion they can reduce a lot of code and still maintain readability.

#5 - Coroutines

While coroutines are still experimental in Kotlin, I think they’re worth mentioning as an exciting new way to approach asynchronous code.

fun startCountDown(hello: Text, button: Button) {
    launch(UI) { // launch coroutine in UI context
        for (i in 10 downTo 1) { // countdown from 10 to 1
            hello.text = "Countdown $i ..." // update text
            delay(1000) // wait a second
        }
        hello.text = "Done!"
    }
}

In my first example I’m starting a launch coroutine on UI thread. There’s a counter inside that pauses for 1 second before it continues. In this case it doesn’t block the UI like you might expect, the delay function is just suspending the coroutine. The code inside launch is thread safe and can readily update the UI.

fun startCountDown(hello: Text, button: Button) {
    var job = launch(UI) { // launch coroutine in UI context
        for (i in 10 downTo 1) { // countdown from 10 to 1
            hello.text = "Countdown $i ..." // update text
            delay(1000) // wait a second
        }
        hello.text = "Done!"
    }
    button.setOnClickListener{ job.cancel() }
}

If you want the ability to cancel the coroutine, it’s possible to assign the launch builder to a variable. And then from outside the code it’s possible to stop the whole coroutine.

I like coroutines because I think they’re an easy way to contain async code in the context where the code is being executed. It might be worth considering as a way to reduce complexity while still being thread safe.

Coroutines are big topic and if you want to read more about them check out https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md

Conclusion

While Java has historically served the needs of the Android development community, it’s great that Google has expanded their first party support to give us more options.

If you’d like to give Kotlin a try, there’s very little configuration you have to do in order to bring it into a project. And since it’s supported by Google, you can easily convert existing code to Kotlin or make new classes in Kotlin that interop with your Java code.

Thanks for reading and I hope this has been useful! If you manage to figure out the cure for global warming or worldwide pony delivery, be sure to let us know in the comments!

If you want to read more on Kotlin, check out https://kotlinlang.org/

Like what you've been reading? Join us and help create the next generation of prototyping and collaboration tools for product design teams around the world. Check out our open positions.