29

Kotlin For Android: An Introduction [FREE]

 4 years ago
source link: https://www.tuicool.com/articles/hit/NbQB7nU
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Update Note : Matei Suica updated to this tutorial to Android Studio 3.3. Joe Howard made the previous update, and Eunice Obugyei wrote the original tutorial.

Before 2017, Android app developers almost exclusively used the Java 6 programming language, with support following for later additions. Java 6 was introduced in 2006, two years before the release of Android devices.

JetBrains developed IntelliJ IDEA, which is the basis for Android Studio. In 2011, the company introduced the Kotlin language, but few Android developers started using it. Though Kotlin was production ready, the language wasn’t stable. When important changes in the language happened, developers had to change their codebase. Five years later, Kotlin released 1.0. Thanks to all the early adopters for this great moment!

At Google I/O 2017, Google announced that Android will support Kotlin as a first-class programming language from now on. For this to happen, the 3.0 release of Android Studio (AS) integrated Kotlin support out of the box! The following three minor releases of AS continued to improve the Kotlin support and the tools available.

Kotlin is a statically-typed, modern programming language that runs on a Java Virtual Machine (JVM) by compiling Kotlin code into Java byte-code. It can also be compiled to JavaScript source code and to native executables. Kotlin is flexible and has some cool features!

In this Kotlin for Android tutorial, you’ll learn:

  • How to set up your Kotlin environment.
  • How to work with Java and Kotlin in the same project.
  • What makes Kotlin so exciting as a new language.

Note : This tutorial assumes you’re experienced in Android development with Java. If you’re new to the Android world or have big questions about the starter project, please review otherAndroid tutorials. For this tutorial, you need Android Studio 3.3 or later.

Why Kotlin For Android?

Since Android took the world by storm, developers have had few alternatives to Java for app development. Java was the programming language that the most advanced phones were using to run their native apps on their proprietary operating systems. For example, Nokia’s Symbian had Java ME apps. Although its usage is widespread, Java comes with a lot of historical baggage.

Java 8 solved some language issues and even more were corrected with Java 9 and 10. Unfortunately, you have to set the minimum SDK to Android 24 to use all of Java 8’s features, which isn’t an option for many developers. The fragmentation of the Android ecosystem makes it impossible to leave out users with older devices. For most developers, Java 9 and 10 aren’t even on the radar.

Kotlin is the modern programming language solution for Android. There are a few things that make Kotlin a great fit for Android:

  1. Compatibility : It’s compatible with JDK 6, so older devices aren’t left behind.
  2. Performance : It’s on par with Java.
  3. Interoperability : It’s 100% interoperable with Java including annotations.
  4. Footprint : The runtime library for Kotlin is tiny.
  5. Compilation Time : There’s a little overhead on clean builds but it’s way faster with incremental builds.
  6. Learning Curve : It’s easy to learn, especially for people used to modern languages. The Java to Kotlin converter in IntelliJ and Android Studio makes it even easier. You can also use a mix of Kotlin and Java in a project, so take your time learning Kotlin and add it in when you feel comfortable.

While Java 8 is now supported on recent Android releases, recent developer surveys say that Kotlin is gaining ground. The Realm team notes that ”Kotlin is about to change the whole Android ecosystem.” Kotlin is now one of the most loved programming languages out there. It’s poised to dominate Android app development. Above all, it’s a new language! What could be more exciting? iOS developers had their fun in 2014 with Swift. Now, it’s your turn. :]

Getting Started

For this tutorial, you’ll explore Kotlin by working with an app that allows users to search for books, see book covers and share books with friends.

Download the materials using the Download Materials button at the top or at the bottom of this page. Extract and open the starter project in Android Studio 3.3 or later.

It contains three source code files written in Java:

  • MainActivity.java : An Activity that displays the screen for searching and displaying a list of books.
  • DetailActivity.java : An Activity that displays the book cover for the ID passed to it.
  • JSONAdapter.java : A custom BaseAdapter that transforms a JSON object into a list view item.

Build and run the project to see what you’re working with.

Screenshot_1553068423-281x500.png

First things first: Enter your name so that the app can greet you! :]

Screenshot_1553067453-281x500.png

After that, start searching for the books you’re interested in. Type a book or author name in the field and click on Search to get a list of books.

Screenshot_1553067533-281x500.png

Clicking on a row takes you to the second screen where you’ll have the full cover to admire. Isn’t it cool?

Screenshot_1553067631-281x500.png

Setting up Your Environment

Android Studio 3.3 and later support Kotlin right out of the box. Any new projects you create will use Kotlin. Set the language to Kotlin when you create a new activity. You won’t need to create a project for this tutorial since it’s provided as a starter project above:

Screenshot-2019-02-06-at-11.44.41-613x500.png

A popup will encourage you to update your Kotlin plugin in Android Studio 3.3 whenever a new version is available. You can always check your Kotlin plugin version on the Plugins screen by clicking command+shift+a and typing Plugins . Type Kotlin into the search box and check the version on the right:

Screenshot-2019-02-06-at-11.52.12-650x467.png

Working With Java and Kotlin Together

One of the most amazing qualities of Kotlin is that it can coexist with Java. Java code can call Kotlin code and vice versa. You might not even notice that you’re calling code in another language!

From this point forward, you’ll be translating the DetailActivity class into Kotlin.

Single click com.raywenderlich.android.omgandroid in the Project panel on the left-hand side. With the package selected, go to File ▸ New ▸ Kotlin File/Class to create a new Kotlin class. Without the package selected, you won’t see the Kotlin file option.

Screenshot-2019-02-25-at-10.41.40-540x500.png

On the New Kotlin File/Class popup, select Class in the Kind field and enter DetailActivityKotlin as the class name. Click OK .

intro_to_kotlin_17.png

Your new class should look like this:

package com.raywenderlich.android.omgandroid

class DetailActivityKotlin {
}

A few things to note:

  1. Declare Kotlin classes using the keyword class — just like in Java.
  2. By default, if no visibility modifier is present in Kotlin, the item is public .
  3. Classes and methods are final by default. Declare them open if you want to inherit classes and override methods.

Since Kotlin and Java are interoperable, you can use existing Java frameworks and libraries in your Kotlin code files.

Make the class a subclass of AppCompatActivity :

class DetailActivityKotlin : AppCompatActivity() {

}

If needed, click Option + Return to import classes such as AppCompatActivity . Android Studio will usually add the import statements for you if there are no conflicts.

Distinctly from Java, in Kotlin, you append :NameOfParentClass() to the subclass declaration. The trailing parentheses are for the constructor on the parent class.

Now override Activity ‘s onCreate() method. It will look something like this:

import android.app.Activity
import android.os.Bundle

class DetailActivityKotlin: Activity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
  }
}
Note : You can use Android Studio’s code generation functionality to generate the onCreate method. Press Control + O to see a popup with all overridable methods for the class you’re in and choose onCreate

.

intro_to_kotlin_18-463x500.png

Open MainActivity.java and replace the DetailActivity reference in onItemClick() with DetailActivityKotlin .

Your intent creation line should change from:

Intent detailIntent = new Intent(this, DetailActivity.class);

To this:

Intent detailIntent = new Intent(this, DetailActivityKotlin.class);

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 .

kotlindetails-568x500.png

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!

happydog-568x500.png

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-334x500.png

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:

throw NullPointerException()
!!
lateinit var

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 .

The Elvis Operator

The Elvis Operator ( ? :) looks like the ternary conditional operator in Java but works differently. It also looks like Elvis Presley’s hair if you tilt your head 90 degrees to the left :] You can see an example of this when trying to get the length of the cover ID:

val len = coverId?.length ?: 0

If the expression to the left of the Elvis operator is not null , it returns the result of the expression. Otherwise, it returns the expression to the right.

Similarly to an if-else statement, Elvis only evaluates the expression on the right if the one on the left side is null . The equivalent would be:

val len: Int
  if(coverId?.length != null) {
    len = coverId?.length
  } else {
    len = 0
  }

It’s shorter with the Kotlin way, isn’t it?

Type Inference

Kotlin also supports type inference. This means the compiler can deduce variable types from the initializer. You can still declare the type if you want or if the compiler can’t infer it. For example, the types of the imageUrlBase and imageURL variables are inferred from their initializers.

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

The compiler tracks the inferred type of each variable, each as a String . Any values assigned after that to the variable must also be of that String type. For numbers, you need to make the type of variable clear to the compiler.

var longVar = 0L
    var floatVar = 0.0f
    var doubleVar = 0.0
    var integerVar = 0

The Java to Kotlin Converter

I like to call this tool The Kotlinifier. Unfortunately, the JetBrain team isn’t trying to be funny. Still, the converter is the best tool ever made to ease the transition from one programming language to another.

Since Kotlin was made by developers for developers, they knew what language users would want. These tools are what the language developer team used to transition themselves from Java to Kotlin. That’s why the converter is so good!

Try it out. Take this sanity-saving feature for a test drive by converting the DetailActivity.java file to Kotlin.

Open the DetailActivity.java class and go to Code ▸ Convert Java File to Kotlin File or use the shortcut Command + Shift + Option + K :

Screenshot-2019-02-06-at-12.02.54-606x500.png

You will get a notice like shown, click OK . This will replace the Java file with a Kotlin one. This notice however is only showed when necessary, so don’t always expect it.

intro_to_kotlin_14-700x256.png

That’s it. You’ve converted a Java class into a Kotlin class. :]

notbad-320x320.png

Compare the converted DetailActivity with the DetailActivityKotlin class. Pay attention to the choices the converter made. It doesn’t always make the best choices, but it does produce working code. Always review the converted code when you use this feature. You can even learn language features from the converter!

Now, reset MainActivity to refer to the converted code:

Intent detailIntent = new Intent(this, DetailActivity.class);

Build and run and go to the detail screen, and you’ll see the converted code works as well as the code you had in DetailActivityKotlin . :]

Kotlin is Evolving

While other programming languages have already reached maturity, Kotlin is still in its infancy. The latest version right now is 1.3, and it came with a lot of new features. Some of the features were already in the language as experimental features and some are all new. Some are also improvements to already existing constructs. Here are some highlights that you should know about.

Coroutines

Coroutines are a more advanced feature of Kotlin that allows developers to run asynchronous code. You might not know about coroutines now, but it’s worth mentioning that the feature is now stable. If you ever need to run a non-blocking piece of code, check out Coroutines .

Improvements to when expression

Kotlin’s equivalent to Java’s switch is when . In Kotlin 1.3, the when subject can be captured on the spot. You no longer need to assign a val right before the block.

when (val response = executeRequest()) {
            is Success -> response.body
            is HttpError -> throw HttpException(response.status)
        }

More Numbers

For some applications, it makes sense to use unsigned number types. Getting the sign out of the way makes room for new possibilities. Kotlin 1.3 brings back the old unsigned concept: UByte , UShort , UInt and ULong are all new and experimental. Use them carefully!

Code Style Support in the IDE

Remember Java Coding Conventions? Yeah, me neither. Kotlin has a pretty solid coding conventions document that all Kotlin developers should read, learn and follow religiously. That’s why now you can set up your IntelliJ-based IDE to format your code The Kotlin Way instead of its default. This will help you keep your code nice and respectful of the recommendations.

There are many more changes in Kotlin 1.3. To check them all out, go to the changelog . Once you’re more advanced in the art of Kotlin, you’ll be amazed at how useful these additions are.

Where To Go From Here?

Congratulations! You’ve learned a lot about Kotlin! You recoded a Java Activity in Kotlin and used the Kotlin plugin to convert a Java source file into a Kotlin source file. Find the final project and compare your results by clicking the Download Materials button at the top or bottom of this tutorial.

I suggest reading further on Null Safety in Kotlin in the documentation.

You can also use the Kotlin online compiler to try out code samples and improve your knowledge of the language.

You’ve only scratched the surface of Kotlin’s amazing possibilities. If you’re excited by what you’ve read here, check out other Kotlin topics. There’s a lot to learn about Data Classes , Extensions , Lambdas , or String Templates .

I hope you enjoyed this Kotlin for Android tutorial. If you have any questions or comments, join the forum discussion below!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK