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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Kotlin For Android: An Introduction
25 mins
- Why Kotlin For Android?
- Getting Started
- Setting up Your Environment
- Working With Java and Kotlin Together
- Some Things Never Change
- How Cool is Kotlin?
- Declaring Variables
- Null Safety
- Nullable Types and Non-Null Types
- Late Initialization Variables
- Safe Calls
- The !! Operator
- The Elvis Operator
- Type Inference
- The Java to Kotlin Converter
- Kotlin is Evolving
- Coroutines
- Improvements to when expression
- More Numbers
- Code Style Support in the IDE
- Where To Go From Here?
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. :]
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
.