Why we use Kotlin in our Android project

Freddie Wang
6 min readJun 4, 2017

--

Google has announced that Kotlin is supported officially in Android Studio 3.0. That’s a big news for Android developers. Before Google supports Kotlin, we’ve already used Kotlin in our Android project since 2016. I am going to share why we decided to use Kotlin and what language features we are using in our project.

Why we use Kotlin

In 2016, we kicked off a project and need to finish in very short time. In that time, Kotlin 1.0 had released for a while but we had never used Kotlin yet. We took some time to survey Kotlin before we started our project. Finally, we decided to use Kotlin because

- 100% java interoperability

One of the best feature in Kotlin is that it can mix java code in some project and use existed java libraries without any problem. We don’t have legacy java code in our project but we need to use some awesome libs like Dagger 2, Retrofit, RxJava, etc.

- Concise syntax

Kotlin was designed for solving problems. One of the main purposes is to write clean code easier than Java. That’s very important for us.

- Reduce the dependencies

Kotlin has a compact runtime library and can replace some large Java libraries like guava. Using large java libraries would not a problem in server-side or desktop-side, but it would be a problem in Android because of the 65K methods limitation in dex.

- Compatible with old android devices

Kotlin 1.0 bases on Java6, that means it can support any android device. That’s also important to an android application.

After Kotlin 1.1, Kotlin also supports Java 8. It is better to not use platform-dependent functions in Android projects.

What language features we are using

- Nullability

In all of Kotlin’s features, nullability support is our favorite one. Kotlin supports the nullable variable out-of-box. With the nullability support, we can just let compiler to check null for us, so it does keep the source code clean and readable. Here are some examples

var output: String
output = null //compile complains
var output: String?
output = null //OK
//don't need to check null in every field
val name = bob?.department?.head?.name field

- Lambda Expressions

Another good feature is lambda expressions. Although Java 8 also supports lambda, so far not many projects are using Java 8 in Android. Kotlin supports lambda and can be run on most android devices. In our project, we also use lots of lambda expressions in UI code (with anko) so we don’t need to set lots of listener or use another view-binding library like ButterKnife.

For example, we can create a custom back button like this. It looks better than Java version, doesn’t it?

backButton = imageButton {
id = R.id.my_back_button
imageResource = R.drawable.ic_back
onClick {
onBackPressed()
}
}

- Extension

Extension is also another awesome feature in Kotlin, it helps us to extend some Android function without creating a base class. For example, we created an extension of Fragment. We can use the same function for swapping fragment in any fragment and don’t need to create a BaseFragment class.

fun Fragment.addFragment(fragment: Fragment) {
fragmentManager.beginTransaction()
.setCustomAnimations(R.anim.slide_left_in,
R.anim.slide_left_out,
R.anim.slide_right_in,
R.anim.slide_right_out)
.add(R.id.container, fragment)
.addToBackStack(fragment::class.java.simpleName)
.hide(this)
.commit()
}
//In another Fragment, don't need to write a BaseFragment class
onClick { addFragment(AnotherFragment()) }

Another example for Boolean-To-Int conversion. That is useful if you need to convert values for json. Sometime you need to use integer in json rather than boolean. It is about the client-server design problem…:)

fun Boolean.toInt(): Int {
return if (this) 1 else 0
}

fun Int.toBoolean(): Boolean {
return this != 0
}
//In another data class, we can use the extension like this
data.intValue = true.toInt()
data.booleanValue = 1.toBoolean()

- Named arguments and default arguments

Writing a readable code is the most important thing in our team, so named arguments is another feature we like a lot. Before using Kotlin, it was annoying to us when we created functions with several parameters (more than 4). If you are not the author, you may not understand what it means quickly. For example, we used Catmull-Rom spline to calculate the control point for the points in a path. The function needs 7 parameters. If we don’t use named arguments, other team members cannot understand it easily.

fun catmullRomControlPoint(controlPoint: PointF, 
prevPoint: PointF,
currentPoint: PointF,
nextPoint: PointF,
delta1: Double,
delta2: Double,
alpha: Float) {
...}//Not use named argumentscatmullRomControlPoint(controlPoint1,
point0,
point1,
point2,
delta1,
delta2,
alphaValue)
//Use named arguments
catmullRomControlPoint
(controlPoint = controlPoint1,
prevPoint = point0,
currentPoint = point1,
nextPoint = point2,
delta1 = delta1,
delta2 = delta2,
alpha = alphaValue)

- Data class

Java doesn’t support struct like other languages, when you want to create pure object (POJO), that is an annoying and boring task. Java developers can use lombok to make this job easier, but the Kotlins’ data class is more easier to use. You can create the data class like below and that’s it!! Kotlin compiler would generate the getter and setter automatically.

data class User(var name: String, var email: String, var age: Int)

If you are using gson, you can also add the annotation on it.

data class User(@SerializedName("userName") var name: String, 
@SerializedName("userEmail") var email: String,
var age: Int)

Except language features, Kotlin is also accompanied with some useful libraries. What we use mostly are stdlib and Anko (for Android)

- Anko

Anko is a Kotlin library which consists several parts to make Android development faster and easier. We use mostly is Anko Layout. it provides a DSL to make android UI instead of traditional xml. With the Anko DSL, you can create a UI page like this

//anko DSL
class MainActivityUi : AnkoComponent<MainActivity> {
lateinit var aButton: Button
override fun createView(ui: AnkoContext<MainActivity>): View =
with(ui) {
relativeLayout {
aButton = button {
textResource = R.string.ok
onClick {
toast(“click button”)
}
}
}.lparams(width = matchParent, height = wrapContent) {
alignParentBottom()
}
}
}

In our project, we encapsulate most UI-related code into such XXXUi class, so we separate our business logic easily. When we used Anko, we found there are some advantages

  • More flexible than xml
  • Performance is better

Because anko created all UI views programmatically, it can add conditions in the DSL (It is lambda expressions).

relativeLayout {
...
if (shouldShowToolTip) {
toolTipLayout()
}
}

If using xml, you cannot do the same thing in the xml directly. You may need to use a ViewStub or add the toolTipLayout into the RelativeLayout dynamically.

In our project, we don’t use any layout xml, we only use xml for values. In our tests, the UI creation time is also good in older android devices. Some people did the report that shows the performance is up-to 400% better!

Except the DSL, Anko also provides some useful functions for asynchronous tasks, We use it to load bitmap to an image view.

doAsync {
val bitmap = loadImage()
uiThread {
imageView.imageBitmap = bitmap
}
}

Some drawbacks

- Not so convenient when using mockito in unit tests

Not like java, The class in Kotlin is final class by default. Only the class that declared with open can be mock by Mockito. Sometimes it is not very convenient for unit tests. Fortunately, there are some solutions

  • Use Mockito 2, but you still need to create a org.mockito.plugins.MockMaker file
  • Use all-open plugin that was provided after Kotlin 1.0.6
  • Change the design, Use the interfaces as possible

We decided to change our design, mock the interface in unit tests. It can help us to avoid the “bad smell” in our source code.

- Anko UI preview tool

There is an anko UI preview tool for android studio and intelliJ. When we started using Kotlin and anko, the preview tool only works on previous android studio, so we never run anko UI preview tool successfully…lol.

Even that, by the powerful anko DSL, we don’t really need a preview tool. We still can make our UI without any problem. No preview tool is not a big deal for us.

Conclusion

Before we started using Kotlin in our project, we still had some concerns at the beginning. After the more Kotlin code we wrote, The more confident we had that we made a correct decision. Now all of our team members are enjoying writing Kotlin code, it improve our productivity very much. So you are not using Kotlin in your android project, just use it. You won’t regret!

--

--

Freddie Wang

I’m a software engineer from Taiwan and living in Japan now.