Basics of Kotlin support in Android

August 16th, 2017| By

Introduction

  • Google has added Kotlin language support in Android Studio 3.0 for developing Android applications. So what is Kotlin? Kotlin is an OSS statically typed programming language that targets the Android, JVM, JavaScript and Native. It’s developed by JetBrains. It was started in 2010 and is open source under Apache 2.0 license. The first official release 1.0 was in February 2016.
  • Kotlin is both object-oriented and functional programming. You can use it in both styles, or combine both. With support for features such as higher-order functions, function types and lambdas, Kotlin is a great choice if you’re doing or exploring functional programming.
  • Kotlin is more concise. Estimations have given approx. 40% cut in the number of lines of code. It’s also more type-safe, e.g. support for non-nullable types makes applications less prone to NPE’s(Null Pointer Exceptions). Other features including smart casting, higher-order functions, extension functions and lambdas with receivers provide the ability to write expressive code.
  • Kotlin can be used for any kind of development like server-side, client-side, web and Android. With Kotlin/Native currently in the works, support for other platforms such as embedded systems, macOS and iOS is coming. People are using Kotlin for mobile and server-side applications, client-side with JavaScript or JavaFX, and data science.

Installing the Kotlin plugin

  • The Kotlin plugin is inbuilt with Android Studio starting from version 3.0. If you are using an earlier version, you'll need to install the Kotlin plugin. Go to File -> Settings -> Plugins -> Install JetBrains plugin… and then search for and install Kotlin. If you are at the "Welcome to Android Studio" screen, choose Configure -> Plugins -> Install JetBrains plugin… You'll need to restart the IDE after this completes.

Create a new project with Kotlin

  • In Android Studio, click File -> New -> New Project. Or if you've just opened Android Studio and you are at the ‘Welcome to Android Studio’ window, click Start a new Android Studio project.
  • On the first screen, check Include Kotlin support. That's the only difference.
  • Click Next and continue through the wizard until you're done.

Add Kotlin to an existing project

  • If you want to add Kotlin code to an existing project, simply click File -> New and select one of the various Android templates. If you don't see the list of templates in this menu, first open the Project window and select your app module.

  • In next screen, select Source Language as Kotlin to add kotlin language support.
  • Continue through the wizard, and you're done. Alternatively, you can click File -> New -> Kotlin File/Class to create a basic file.
  • By default, new Kotlin files are saved into src/main/java/. It's easier to see both Kotlin and Java files in one location, but if you'd prefer to separate Kotlin files from your Java files, you can put Kotlin files under src/main/kotlin/ instead. If you do, then you need to include this directory in your apps build.gradle file under sourceSets configuration:
android {
  sourceSets {
      main.java.srcDirs += 'src/main/kotlin'
  }
}

 

Convert existing Java code to Kotlin code

  • In Android Studio 3.0, open a Java file and select Code -> Convert Java File to Kotlin File. Or, create a new Kotlin file (File -> New -> Kotlin File/Class), and then paste your Java code into that file—when prompted, click Yes to convert the code to Kotlin. You can check Don't show this dialog next time, which makes it easy to dump Java code snippets into your Kotlin files.

Example with difference:

import android.app.Activity
import android.os.Bundle
public class MainActivity: Activity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
   }
}

 

import android.app.Activity
import android.os.Bundle
public class AnotherActivity: Activity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
   }
}

 

Configuring Your Project to Use Kotlin

  • After converting your project to use and run kotlin, you’ll still need to configure Kotlin every time you want to use it in a new project. Thanks to the Kotlin plugin, configuring a project to use Kotlin couldn’t be simpler: just select Tools from the Android Studio toolbar, followed by Kotlin and Configure Kotlin in Project.

This opens a popup where you can choose to configure Kotlin for:

  • all modules
  • all modules containing Kotlin files
  • or a single, named module
  • Alternatively, you can configure Kotlin by selecting Help from the Android Studio menu, followed by Find Action… In the Find Action bar, type ‘Configure Kotlin in Project’, and then select this option when it appears.
  • The ‘Configure Kotlin in Project’ option makes a number of tweaks to your project’s build.gradle files. Open your project-level build.gradle file, it will look something like this:
buildscript {
 //Declares the version of Kotlin that is supported. You’ll notice that the version of Kotlin is mentioned in both the buildscript classpath and in your project’s compile dependencies - the version number must be the same in both places//
 ext.kotlin_version = '1.0.5-2'
 repositories {
   jcenter()
 }
 dependencies {
   classpath 'com.android.tools.build:gradle:2.2.2'
    
   //Declares the Kotlin Gradle plugin as a classpath dependency//
   classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
 }
}

allprojects {
 repositories {
    jcenter()
 }
}

Now, let’s check module-level build.gradle file:


apply plugin: 'com.android.application'

//Applies the Kotlin Android plugin//

apply plugin: 'kotlin-android'
android {
 compileSdkVersion 25
 buildToolsVersion "24.0.0"
 defaultConfig {
   applicationId "com.example.YourPackageName"
   minSdkVersion 21
   targetSdkVersion 25
   versionCode 1
   versionName "1.0"
 }

 buildTypes {
   release {
     minifyEnabled false
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
   }
 }

 

//Although Gradle will compile any Kotlin files it finds in src/main/java, it’s good to store your Kotlin files in a different Kotlin directory. Here, you can see that the Kotlin plugin has added a src/main/kotlin declaration to build.gradle, but note that it hasn’t actually created this directory, so you’ll have to create it yourself.//

 sourceSets {
   main.java.srcDirs += 'src/main/kotlin'
 }
}

dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
   exclude group: 'com.android.support', module: 'support-annotations'
 })

 compile 'com.android.support:appcompat-v7:25.0.1'
 testCompile 'junit:junit:4.12'

 //Adds the Kotlin Standard Library as a project dependency//

 compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

repositories {
 mavenCentral()
}

 

Finally, sync your changes either by clicking Sync Now from the popup that appears or by clicking the Sync Project with Gradle Files icon in Android Studio’s toolbar.

Kotlin Language Syntax

Defining packages

Package specification should be at the top of the source file:

package my.test
import java.util.*

It is not required to match directories and packages: source files can be placed arbitrarily in the file system.

Defining functions

Function having two Int parameters with Int return type:

fun sum(a: Int, b: Int): Int {
return a + b
}

 

Function with an expression body and inferred return type:

fun sum(a: Int, b: Int) = a + b

 

Function returning no meaningful value:

fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}

 

Unit return type can be deleted:

fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
Defining local variables

Assign once (read-only) local variable:

val a: Int = 1  // immediate assignment
val b = 2   // `Int` type is inferred
val c: Int  // Type required when no initializer is provided
c = 3       // deferred assignment

Mutable variable:
var x = 5 // `Int` type is inferred
x += 1

 

Comments

Just like Java and JavaScript, Kotlin supports end-of-line and block comments.

// This is an end-of-line comment

/* This is a block comment
on multiple lines. */

 

Unlike Java, block comments in Kotlin can be nested.

Using string templates
var a = 1
// simple name in template:
val s1 = "a is $a"​
a = 2
// arbitrary expression in template:
val s2 = "${s1.replace("is", "was")}, but now is $a"

 

Using conditional expressions
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}

Using if as an expression:

fun maxOf(a: Int, b: Int) = if (a > b) a else b

 

Using nullable values and checking for null

A reference must be explicitly marked as nullable when null value is possible.

Return null if str does not hold an integer:

fun parseInt(str: String): Int? {
// function logic
}

 

Use a function returning nullable value:

fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
​
// Using `x * y` yields error because they may hold nulls.
if (x != null && y != null) {
// x and y are automatically cast to non-nullable after null check
println(x * y)
}
else {
println("either '$arg1' or '$arg2' is not a number")
}
}

or

if (x == null) {
println("Wrong number format in arg1: '${arg1}'")
return
}

if (y == null) {
println("Wrong number format in arg2: '${arg2}'")
return
}


// x and y are automatically cast to non-nullable after null check
println(x * y)

 

Using type checks and automatic casts

The is operator checks if an expression is an instance of a type. If an immutable local variable or property is checked for a specific type, there's no need to cast it explicitly:

fun getStringLength(obj: Any): Int? {
if (obj is String) {
// `obj` is automatically cast to `String` in this branch
return obj.length
}
​
// `obj` is still of type `Any` outside of the type-checked branch
return null
}

or

fun getStringLength(obj: Any): Int? {
if (obj !is String) return null
// `obj` is automatically cast to `String` in this branch
return obj.length
}

or even

fun getStringLength(obj: Any): Int? {
// `obj` is automatically cast to `String` on the right-hand side of `&&`
if (obj is String && obj.length > 0) {
return obj.length
}
return null
}

 

Using a for loop

val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}

or

val items = listOf("apple", "banana", "kiwi")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}

 

Using a while loop
val items = listOf("apple", "banana", "kiwi")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
Using when expression
fun describe(obj: Any): String =
when (obj) {
1          -> "One"
"Hello"    -> "Greeting"
is Long    -> "Long"
!is String -> "Not a string"
else       -> "Unknown"
}
Using ranges

Check if a number is within a range using in operator:

val x = 10
val y = 9
if (x in 1..y+1) {
println("fits in range")
}

 

Check if a number is out of range:

val list = listOf("a", "b", "c")
​if (-1 !in 0..list.lastIndex) {
println("-1 is out of range")
}

if (list.size !in list.indices) {
println("list size is out of valid list indices range too")
}

Iterating over a range:
for (x in 1..5) {
print(x)
}

or over a progression:
for (x in 1..10 step 2) {
print(x)
}

for (x in 9 downTo 0 step 3) {
print(x)
}

 

Using collections

Iterating over a collection:

for (item in items) {
println(item)
}

 

Checking if a collection contains an object using in operator:

when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}

 

Using lambda expressions to filter and map collections:

fruits

.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.toUpperCase() }
.forEach { println(it) }

 

Kotlin Android Extensions

  • Kotlin has inbuilt android extensions plugin that can remove the boilerplate code that developers hate to write when referencing any view in activity or fragment. Due to this a lot of time can be saved for the developers to easily reference number of views in the class files.
  • As of this added extension, in Android development, findViewById method will not be used and it will also help in offering you the benefits without the drawback of having to write any additional code.
  • Configure the dependency by adding the following line in your project-local build.gradle file.

apply plugin: 'kotlin-android-extensions'

 

  • Now you can directly reference the view from your xml layout in your kotlin class file as helloTextView.setText("Hello, world!"), where helloTextView is the id of the textview added in the xml layout. That’s it, now you don’t need to add findViewById to refer views in the class files.

What’s next in Kotlin?

  • This was just a glimpse of what kotlin is and how to switch over from java to kotlin with basic knowledge. Furthermore, if you are an Android developer looking forward to work with kotlin language instead of java, then, you should try with Android Overview and Kotlin reference from its official documentation.
  • With this, you’ve learned a new programming language that has added features for type safety and error-prone to NPE’s and it has new syntax differing from java. However, you can also use the Kotlin online compiler to try out your own code samples and logics to improve your knowledge about the language.