Kotlin For Android: An Introduction

See how Kotlin For Android makes developing Android apps far more enjoyable. Learn how simple it is by creating your very own book searching app. By Matei Suica.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 2 of 3 of this article. Click here to view the first page.

Some Things Never Change

As you would for a Java Activity, you need to declare your Kotlin Activity in AndroidManifest.xml. Add the following code under the DetailActivity declaration inside the application tag:

<activity
    android:name=".DetailActivityKotlin"
    android:label="@string/activity_details_kotlin"
    android:parentActivityName=".MainActivity">
  <meta-data
      android:name="android.support.PARENT_ACTIVITY"
      android:value=".MainActivity"/>
</activity>

Working with XML files in general hasn’t changed including AndroidManifest, layout files, styles and resources. Regardless of an Activity’s programming language, if you don’t register it in the manifest, your app will crash!

Build and run. Select a book from the list to see the empty screen with the title Kotlin Book Details.

How Cool is Kotlin?

Before you dive deeper into Kotlin’s features, go back to DetailActivityKotlin.kt and replace the contents of the file with the following:

  
package com.raywenderlich.android.omgandroid

import android.content.Intent
import android.os.Bundle
import android.support.v4.view.MenuItemCompat
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.widget.ImageView
import android.support.v7.widget.ShareActionProvider
import com.squareup.picasso.Picasso

class DetailActivityKotlin : AppCompatActivity() {

  private val imageUrlBase = "http://covers.openlibrary.org/b/id/"
  private var imageURL = ""
  private var shareActionProvider: ShareActionProvider? = null

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.activity_detail)

    actionBar?.setDisplayHomeAsUpEnabled(true)

    val imageView = findViewById<ImageView>(R.id.img_cover)

    val coverId = this.intent.extras.getString("coverID")

    val len = coverId?.length ?: 0

    if (len > 0) {
      imageURL = imageUrlBase + coverId + "-L.jpg"
      Picasso.with(this).load(imageURL).placeholder(R.drawable.img_books_loading).into(imageView)
    }
  }

  private fun setShareIntent() {

    val shareIntent = Intent(Intent.ACTION_SEND)
    shareIntent.type = "text/plain"
    shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Book Recommendation!")
    shareIntent.putExtra(Intent.EXTRA_TEXT, imageURL)

    shareActionProvider?.setShareIntent(shareIntent)
  }

  override fun onCreateOptionsMenu(menu: Menu): Boolean {

    menuInflater.inflate(R.menu.main, menu)

    val shareItem = menu.findItem(R.id.menu_item_share)

    shareActionProvider = MenuItemCompat.getActionProvider(shareItem) as ShareActionProvider

    setShareIntent()

    return true
  }
}

On the surface, the code resembles Java, but there are some Kotlin language specifics that you’ll get into in the next section.

Build and run, select a book and see if you get a cover this time. Oh, look, you do!

Declaring Variables

Declaring variables in Kotlin is simple and clear. To be as expressive as possible, you must be familiar with all that Kotlin can and can’t do when it comes to variables. Here are some variable declarations you’ll use often:

var item = "house"
val points = 35

var car: String = "BMW"

What’s the difference between val and var? You can’t later reassign variables that you declare with val. Doing so triggers a compiler error. But you can with var. This is the difference between the two.

points = 36

You’ve already said you only have 35 points, so don’t try to cheat! This way of declaring variables is similar to Java’s final.

The other thing that’s different in the last declaration is that there’s also a variable type. In Kotlin, type inference works quite well. That’s why most of the time you don’t need to explicitly declare the type of a variable. As you’ll see later, you must do this when it comes to Optional type, which can be null. For the car variable above, the type isn’t necessary, but it’s nice to let the Kotlin compiler know that it’s a String and will never be something else.

var highScore = points + 999

As you can see, Kotlin can figure out by itself that highScore is an integer here.

Null Safety

A common frustration with programming languages is accessing a member of a null reference. A null reference occurs when you declare an object variable without giving it a value, or when you assign null to that variable. When the program runs and tries to access that variable, it doesn’t know where to look because it doesn’t exist.

The most common result is your application coming to an abrupt halt and crashing. You might be familiar with Java’s almighty NullPointerException. Apologies in advance for any flashbacks. :]

null_pointer_exception

One of Kotlin’s greatest features is that its type system aims to eliminate the NullPointerException, a goal known as void safety.

In Kotlin, the possible causes of a NullPointerException are:

  • External Java code.
  • An explicit call to throw NullPointerException() (NPE).
  • Usage of the !! operator.
  • A lateinit var not initialized before access.

Nullable Types and Non-Null Types

Kotlin has nullable and non-null types. If you don’t declare a variable as nullable, you can’t assign it a null value. The compiler enforces this, making it harder to unintentionally crash your app.

In contrast to Java, all variables must be initialized at the point of declaration, in a constructor or in a init, except lateinit var.

To declare a variable as nullable, you have to append a ? to its type at the point of declaration, as you see in this shareActionProvider declaration:

  
private var shareActionProvider: ShareActionProvider? = null

Late Initialization Variables

Late initialization variables are the developer’s promise that they will initialize the variable before accessing it. This is one of the most common NPE causes. To declare a variable without initializing it in the constructor or an init block, prepend lateinit:

class SomeClass {
  private lateinit var myName: String

  fun methodThatAccesses() {
    myName.trim()
  }

  fun methodThatAssigns() {
    myName = "initialize the variables!"
  }
}

Now, if you were to call methodThatAccesses first, the app would crash. You promised that you’d initialize myName before accessing it and you didn’t. On the other hand, if you called methodThatAssigns first, there would be no crash.

This can be useful when you have something you know for sure you’ll initialize in time but you can’t do it in the constructor or in an init block. In Android, views are assigned in the onCreate() method. If you need one of the views to be a class member and don’t want to deal with nullability everywhere, it makes sense to declare it lateinit.

Safe Calls

To access a property or method on a nullable variable in Java, you would first do a null check. You can see this in DetailActivity.java:

if (shareActionProvider != null) {
  shareActionProvider.setShareIntent(shareIntent);
}

With Kotlin, you can simplify the above expression with the use of the safe call operator ?.. The property or method is only called when the nullable variable is not null.

  
shareActionProvider?.setShareIntent(shareIntent)

Here, setShareIntent is only called when the shareActionProvider property is not null.

The !! Operator

As stated earlier, this operator is one of possible causes of the dreaded NullPointerException. If you’re sure a nullable reference is not null, feel free to use the !! operator to dereference your object.

You can see an example of this in setShareIntent():

shareActionProvider = MenuItemCompat.getActionProvider(shareItem!!) as ShareActionProvider

Here, a NullPointerException is thrown if the shareItem variable is null.

Matei Suica

Contributors

Matei Suica

Author and Author

Nicole Hardina

Editor

Over 300 content creators. Join our team.