Mobile - - By Abbas Suterwala

Kotlin Techniques that Improve Your Android Code

This article covers techniques which make writing Android code in Kotlin efficient and easy. Kotlin is a general-purpose language that compiles to Java bytecode, developed by JetBrains which makes IntelliJ IDE. You can find the code for this article at GitHub

Using Static layout imports in Kotlin

One of the pain points of working with Android is when we want to use one of the views in the activity. We have to use the ‘findViewById()’ function and then type cast it to the appropriate view type. Kotlin takes a different approach: it lets you import all the views in your layout file. For example, suppose we have a layout file as below

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.kotlineffiecienttechniques.MainActivity2">

    <TextView android:id="@+id/maintextview"
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

And the activity code which updates the text of the maintextview using static imports:

package com.kotlineffiecienttechniques

import android.support.v7.app.ActionBarActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main_activity2.*


public class MainActivity2 : ActionBarActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main_activity2)
        maintextview.text = "Hello Static Import!"

    }

}

In the above code if you see we have ‘statically imported’ all the views using the import statement

import kotlinx.android.synthetic.main.activity_main_activity2.*

Once you have done this you can change the textview as follows:

maintextview.text = "Hello Static Import!"

For the above code to compile, you will have to add the following in the dependencies of your build.gradle:

dependencies {
    compile 'org.jetbrains.anko:anko-sdk21:0.9' // sdk19, sdk21, sdk23 are also available
    compile 'org.jetbrains.anko:anko-support-v4:0.9' // In case you need support-v4 bindings
    compile 'org.jetbrains.anko:anko-appcompat-v7:0.9' // For appcompat-v7 bindings
}

Apply the plugin:

apply plugin: 'kotlin-android-extensions'

And add the following in buildscript::dependencies

 dependencies {
        classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
    }

With the above changes if you build and run the app you will see the activity as shown below
Activity with Static imports

Creating POJO classes in Kotlin

In many applications when we want to convert JSON/XML to objects. For this, we need classes which hold the data of the JSON/XML when you are using REST services. Defining such objects (also known as POJO in Java) is more convenient in Kotlin. Suppose you want to define a POJO in Java to represent a book, the code for that would be as follows

public class Book {

    private String ISBN;
    private float price;
    private int quantity;
    private String title;
    private String description;

    public String getISBN() {
        return ISBN;
    }

    public void setISBN(String ISBN) {
        this.ISBN = ISBN;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

The same POJO with the same functionality if we want to define in Kotlin can be defined as follows

public class Book {
    public var ISBN: String = ""
    public var price: Float = 0.toFloat()
    public var quantity: Int = 0
    public var title: String = ""
    public var description: String = ""
}

Or, to make it more concise, it can be defined as a data class as follows.

data class Book2(var ISBN: String, var price: Float, var quantity: Int,
                 var title: String , var description: String)

This is slightly different from the previous POJO as this has a primary contructor. All parameters need to be passed to the contructor while creating the object. When we define a data class it also adds the methods ‘equals’ , ‘hashCode’ , ‘toString’ . This should be a preferred way to define a POJO in Kotlin.

As you can see above the POJO which was defined in Java in about 50 lines of code. In Kotlin this could be done in 7 lines or in 2 lines using data classes.

Constructors and Inheritance in Kotlin

Kotlin makes it easier to write constructors for your classes. The primary constructor becomes a part of the class header. It follows after the name of the class. So suppose we had a primary constructor for our Book class the code would look as follows

public class Book (var ISBN: String, var price: Float, var quantity: Int,
                   var title: String , var description: String){

}

The above code defines a primary constructor in which we pass values. The members are initialized with the values.

Now to create an object of the Book class would be as follows

val book1 = Book("123456", 43.0f, 4, "Kotlin for you", "Book on Kotlin")

This removes the boilerplate code of writing separate constructor function. The constructor which just copies the passed parameters into the member variables. Writing such a constructor would be necessary to do if you were using Java to write your Android app.

Inheritance in Kotlin is safer too; all Kotlin classes cannot be extended unless they are defined as open.

So if you were to extend Book, then it should be defined as follows

open public class Book (var ISBN: String, var price: Float, var quantity: Int,
                   var title: String , var description: String){

    open fun getShippingPrice():Float {
        return price;
    }
}

Suppose we have a subclass HardCoverBook which extends the Book class, it also overrides the getShippingPrice function. The code for that would be as follows:

class HardCoverBook(ISBN: String, price: Float, quantity: Int,
                    title: String , description: String) :
        Book(ISBN, price, quantity, title, description) {

    override fun getShippingPrice():Float {
        return price + 3.0f;
    }
}

Using lambda functions in Kotlin

In Android, we often have functions that take one interface as a parameter. In such cases using the Kotlin lambda functions is convenient. See how we can set an onClickListner on a view

maintextview.setOnClickListener({ view -> Toast.makeText(this, "Showing Toast", Toast.LENGTH_SHORT).show(); })

It is just one line. We don’t even need to specify the type of the parameter view as it can be statically inferred. The equivalent code in Java would be

maintextview.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(this, "Showing Toast", Toast.LENGTH_SHORT).show(); 
    }
});

If we run the program by setting the onClickListener as per the Kotlin code shown above, you should see the toast as shown below:
Activity with toast

Conclusion.

The above are a few examples which help to write concise code in Kotlin for Android. Kotlin is a new language, but is supported by Jetbrains and has good potential. The apk size increases while using Kotlin rather than Java for your Android program. But you might be able to develop code faster in it. So have fun writing your next Android app in Kotlin.

Sponsors