An Introduction to Kotlin for Android Developers

Clinton Teegarden
9 min readFeb 20, 2019

If you haven’t heard by now, one of the biggest announcements at Google IO was Android’s official support for Kotlin. Over the past couple of years, Kotlin has gained a large following in the Android Community, and the official support is great response to that by the Android Team at Google.

There are many blogs that already take a deep dive into Kotlin as a language, and I encourage you to check those posts and the official Kotlin Documentation out. The purpose of this blog, however, is to look at an end to end product implemented in Kotlin with an Android only lens. I will demonstrate how to get up and running with Kotlin in the latest version of Android Studio, mention a few great Kotlin features that are especially important to Android Developers, and also show you how to do common Android tasks such as adhere to the Model-View-Presenter (MVP) pattern, create parcelables, start activities, etc.

In this blog and in the attached application, you will find the following frameworks and patterns demonstrated: Fresco, RxJava, RecyclerViews, Gson, Model-View-Presenter(MVP) Pattern, Parcelables, Generics, and Kotlin Extensions.

How to Get Started

Android Studio 3.0

At the time of writing this post, Android Studio 3.0 is still in its Canary release. You may, however, start using this today by installing the Canary version alongside your stable version. I would highly suggest that you follow the steps here, so that you may have a stable version of Android Studio for your everyday work alongside your canary version.

Dependencies

If you are starting a new project, Android Studio gives you a great option during this process to “include Kotlin Support” on the initial page of the project creation. Simply check that box and step through the rest of the set up that you are familiar with today for a new project. Android Studio will take care of adding the plugins/dependencies necessary for Kotlin. Finally, if you choose to create an initial Activity, this Activity will be generated in Kotlin.

If you are not creating a new project, in your project’s build.gradle file (this is the one that is not inside of your App module), you will need to add a couple plugins and dependencies.

First, be sure you are referencing the Google Maven Repository by adding the below line to your repository’s body:

maven { url 'https://maven.google.com' }

Next, let’s define a common Kotlin Version name which will be used to ensure that your Kotlin plugin and dependency all point to the same version.

At the top of the buildscript body add the following:

buildscript { ext.kotlin_version = '1.1.2-4'//note use the latest version available .... }

Next, still in your project’s build.gradle file, add the following dependency:

dependencies { //note, be sure to reference what you defined as your version name classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" }

Next, moving to your App module’s build.gradle file, add the following plugin to the top of the file:

apply plugin: 'kotlin-android'

finally, add the Kotlin library dependency to your module’s dependencies as well.

//we are referencing the same version name defined in the project build file compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

Creating Kotlin Classes and Activities

You are now ready to get started! You can create activities in the same manner that you are used to with Java support. You simply need to choose Kotlin or Java in the Source Language drop down during the activity creation process.

Creating classes is the same approach that you are used to as well. Simply right click the package where you want the file, select new, and then select whether you want a Java or Kotlin file.

Kotlin Developer Basics

Null Safety

Kotlin has nullable and non-null types to help you avoid those nasty Null Pointer Exceptions (NPE). I highly recommend you check out the Kotlin Documentation for in depth details on this, but here are a few highlights.

First, lets take a look at a non-null type String. In the below example, we demonstrate that we cannot compile code that tries to set our non-null String to null.

var testVar : String = "a test string" testVar = null //error, won't compile

If you must have the option to have a variable set to null, you need to define it as such.

var testVar : String? = "a test string" testVar = null //no issue.

When you use a nullable type, the compiler will enforce that you protect against the possible null pointer.

val testVal : String? = "a test string" val testValCount : Int = testVal.length //wont compile as testVal may be null!

In the above example, you may still need the length of the String. You can do this in a few different ways.

Nullable Type

One approach is to simply allow your integer variable to be a nullable type. However, remember that by doing this, you are just pushing the null down the line and may have to fully address this elsewhere. For instance, for an integer, you will need to address this before you do any calculations with it.

val testVal : String? = "a test string" val testValCount : Int? = testVal?.length //compiles, but testValCount may be null! val testCalc : Int = testValCount * 2 //wont compile....testValCount may be null

Elvis Operator

The Elvis Operator may be one my favorite Kotlin features just for how much code it saves. The Elvis Operator simply allows you to define what should be set in the event that any of the variables throw a null value.

val testVal : String? = "a test string" val testValCount : Int = testVal?.length ?: 0//defaults to 0 in the event that testVal is null val testCalc : Int = testValCount * 2 //this works!

Non-Null Assert

The Non-Null Assert simply forces the code to run similarly to Java. By declaring a Non-Null Assert you are stating that you are sure that the value will not be null and you are prepared to accept the exception if it is.

val testVal : String? = "a test string" val testValCount : Int = testVal!!.length//compiles but may thrown a NPE

The Static Modifier

In Kotlin, there is no Static modifier. Static modifiers are particularly common for identifying constants within Android. With Kotlin comes the Companion Object for such uses cases. Take the following as an example:

class PracticeArea() { companion object { val staticFun = "STATIC FUN" } }

In the above example, the variable staticFun can be accessed in the same manner that you are used to with Java:

Log.i("TAG", PracticeArea.staticFun)

Access/Visibility Modifiers

The Access Modifiers within Kotlin are similar to what you are used to within Java. However, within Kotlin there is an additional Modifier of internal and the default access is different than Java. The default access when one is not explicitly defined is public. The additional internal modifier is similar to the protected modifier except on the module level instead of the package level.

Methods are Final

It is a pretty common practice to override method inherited from super classes. In Kotlin, however, methods default to final and must be explicity set to open to override.

protected fun onViewReceived(){ //is set to final } protected open fun onViewReceived(){ //children can override }

What does Any mean?

In Java you likely got used to seeing and using the Object class. Kotlin has a similar class called Any. All classes within Kotlin have Any as a superclass.

Anonymous Inner Classes

An anonymous inner class is something you likely use in your development process all the time without even realizing it. You do this, when you would like to modify the classes behavior without having to declare a new subclass for it. In many cases, these can now be replaced with proper lambda usages, but you still may find the necessary. The below example is a use case that can be replaced with a lambda expression, but for demo brevity it is used. Note the object expression usage in the anonymous class creation.

//can be replaced with lambda, but shown for demo purposes view.setOnClickListener(object : View.OnClickListener { 
override fun onClick(v: View?) { //do your click stuff... }
})

Android Practices in Kotlin

In the attached application I demonstrate many common practices used in Android development. Definitely be sure to pull in the source code and check it out. Below I have highlighted a few of the most common practices which are easily apparent within Kotlin.

Parcelables

If you have ever needed to bundle your data object to another Activity or Service, you likely have used Parcelables. Implementing a Parcelable in Kotlin is not so apparent, especially when it comes to building your CREATOR.

In the attached application, I demonstrate Parcelables within two separate Data Classes: PracticeArea and ServiceOffering. Below, I have demonstrated how to implement a parcelable by leveraging a Data Class.

data class PracticeArea(val name: String, val imageLink: String,
val subTitle: String, val body: String,
val serviceOfferings: ArrayList<ServiceOffering>) : Parcelable {

/**
* Companion object is used to defined static members to the class..
* in our case the creator.
*/

companion object {
/**
* Parcelable creator.
*
* @JvmField used make the creator implementation visible as a field to Java.
*
*/

@JvmField
val CREATOR = object : Parcelable.Creator<PracticeArea> {
override fun createFromParcel(source: Parcel): PracticeArea? = PracticeArea(source)
override fun newArray(size: Int): Array<out PracticeArea?> = arrayOfNulls(size)
}
}

/**
* Secondary constructor for the parcelable
*/


protected constructor(parcelIn: Parcel) : this(parcelIn.readString(), parcelIn.readString(),
parcelIn.readString(), parcelIn.readString(), parcelIn.createTypedArrayList(ServiceOffering.CREATOR))


override fun writeToParcel(dest: Parcel?, flags: Int) {
dest?.writeString(name)
dest?.writeString(imageLink)
dest?.writeString(subTitle)
dest?.writeString(body)
dest?.writeTypedList(serviceOfferings)
}

override fun describeContents() = 0
}

Starting an Activity

Starting an Activity probably seems like a no brainer. Simply create an intent, pass the current context and the destination activity’s class. However, a Kotlin class reference is not the same as a Java class reference, so this ends up not being as obvious as it may seem. For more information, see the Kotlin Documentation.

//Java Intent mIntent = new Intent(context, DestinationActivity.class); //Kotlin val intent = Intent(context, DestinationActivity::class.java);

findViewById No More

There are many tools to help you do this today in Android, but let’s take a look at how Kotlin solves this problem. Kotlin leverages extension properties to allow you to reference views by their defined IDs.

To do this, you must import sythetic properties via a standard import statement that ends with your Layout's filename.

In the attached example, the HomeActivity and the ServiceListActivity both share the same Layout file, so to access the layout attributes we simply import the following statement.

import kotlinx.android.synthetic.main.activity_list.*

Sometimes, you may want to access these properties on a View. This is typical in use cases such as Adapter’s and ViewHolders. In the demo application attached, we leverage this by importing the following statement.

import kotlinx.android.synthetic.main.list_view_holder.view.*

The above code creates a variable named itemView which we can then use to reference our attributes.

fun bindView(area: PracticeArea?, practiceListener: PracticeListener) {
itemView.listImage.setImageURI(area?.imageLink)
itemView.listTitle.text = area?.name
itemView.listBody.text = area?.body
itemView.listSubTitle.text = area?.subTitle

......
}

Lastly, to leverage Kotlin Android Extensions, simply apply the following plugin at the top of your module’s build.gradle file. No further dependencies are needed.

apply plugin: 'kotlin-android-extensions'

Adapters, RxJava, & More

Please find the attached demo application to learn more about these and other common frameworks used when building an Android application. The Application consists of two Activities each with its own list with the secondary activity being details from what was selected on the first. The content is fed by an RxJava powered class that parses raw json from the assets folder into Kotlin Data Classes. The application is built in a Model-View-Presenter pattern and is fully unit testable.

Road Bumps

During my development process of the demo application, I was leveraging a lot of code that I had in place for other applications written in Java. Through that process, I had to make a couple minor adjustments to the code as it was in order for it to work as expected with Kotlin.

  1. If you currently use GSON, you may be used to leveraging the fromJson(string, class) method. However, I ran into issues with this and Lists/Arrays. Gson throws a casting exception at runtime when trying to pass the java class reference of your Kotlin Data Class for use. To fix this without having to implement another framework, I simply adjusted my code to use a TypeToken instead.
  2. At the time of writing this post, there is currently a bug in the Kotlin Gradle plugin 1.1.2–4 and Android Gradle 3.0.0-alpha-1 which causes the enabling of DataBinding to through a circular dependency error. This can be avoided by switching your kotlin plugin to 1.1.2-2 or by waiting until the bug is fixed.

Closing

The support of Kotlin opens the door for better development and a better experience for Android Developers. You will also find that the Kotlin Documentation is well written full of great examples and Java comparisons for additional help. For more details and helpful Kotlin Android examples checkout the demo application.

Originally published at www.captechconsulting.com.

--

--

Clinton Teegarden

Mobile Lead & Architect @ CapTech. I specialize in delivering products for Fortune 500 clients in Mobile, Services and end to end solutions.