Introduction to Android Activities with Kotlin

Learn about one of the most important concepts within Android apps with this introduction to Android activities tutorial, using Kotlin! By Steve Smith.

4.3 (22) · 1 Review

Download materials
Save for later
Share

Update Note: This tutorial has been updated to Kotlin 1.3 and Android Studio 3.3 by Steve Smith. The previous update was made by Joe Howard and the original tutorial was written by Namrata Bandekar.

Note: The sample code for this tutorial has been updated to be compatible with Android Studio 3.3.2 or later.

When you make an Android app, it’s likely that the first thing you’ll do is plot and plan how you’ll take over the world. Just kidding. Actually, the first thing you do is create an Activity. Activities are where all the action happens, because they are the screens that allow the user to interact with your app.

In short, activities are one of the basic building blocks of an Android application.

In this Introduction to Android Activities Tutorial, you’ll dive into how to work with activities. You’ll create a to-do list app named Forget Me Not and along the way learn:

  • The process for creating, starting and stopping an activity, and how to handle navigation between activities.
  • The various stages in the lifecycle of an activity and how to handle each stage gracefully.
  • The way to manage configuration changes and persist data within your activity.

In addition, you’ll use the Kotlin programming language and Android Studio 3.3. You’ll need to use Kotlin 1.3.21 or later and Android Studio 3.3.2 or later.

This tutorial assumes you’re familiar with the basics of Android development. If you’re completely new to Kotlin, XML or Android Studio, you should take a look at the Beginning Android Development Series and Kotlin For Android: An Introduction before you start.

Getting Started

Download the starter project using the Download materials button at the top or bottom of the tutorial. Open Android Studio 3.3.2 or later, and choose Open an existing Android Studio project. Then select the project you just extracted.

Your subject and new best friend for the rest of the tutorial is Forget Me Not, which is a simple app that lets you add and delete tasks from a list. It also displays the current date and time so you’re always on top of your game!

Run the project as it is now and you’ll see a very basic screen:

At this point, there isn’t much you can do. Your to-do list is empty and the “ADD A TASK” button does nothing when you tap it. Your mission is to liven up this screen by making the to-do list modifiable.

Activity Lifecycle

Before firing up your fingers, indulge yourself in a bit of theory.

As mentioned earlier, activities are the foundations upon which you build screens for your app. They encompass multiple components the user can interact with, and it’s likely that your app will have multiple activities to handle the various screens you create.

Having all these activities doing different things makes it sound like developing an Android app is a complicated undertaking.

Fortunately, Android handles this with specific callback methods that initiate code only when it’s needed. This system is known as the activity lifecycle.

Handling the various lifecycle stages of your activities is crucial to creating a robust and reliable app. The lifecycle of an activity is best illustrated as a step pyramid of different stages linked by the core callback methods:

Adapted from developer.android.com

Following the diagram above, you can picture the lifecycle in action as it courses through your code. Take a closer look at each of the callbacks:

  • onCreate(): Called by the OS when the activity is first created. This is where you initialize any UI elements or data objects. You also have the savedInstanceState of the activity that contains its previously saved state, and you can use it to recreate that state.
  • onStart(): Just before presenting the user with an activity, this method is called. It’s always followed by onResume(). In here, you generally should start UI animations, audio based content or anything else that requires the activity’s contents to be on screen.
  • onResume(): As an activity enters the foreground, this method is called. Here you have a good place to restart animations, update UI elements, restart camera previews, resume audio/video playback or initialize any components that you release during onPause().
  • onPause(): This method is called before sliding into the background. Here you should stop any visuals or audio associated with the activity such as UI animations, music playback or the camera. This method is followed by onResume() if the activity returns to the foreground or by onStop() if it becomes hidden.
  • onStop(): This method is called right after onPause(), when the activity is no longer visible to the user, and it’s a good place to save data that you want to commit to the disk. It’s followed by either onRestart(), if this activity is coming back to the foreground, or onDestroy() if it’s being released from memory.
  • onRestart(): Called after stopping an activity, but just before starting it again. It’s always followed by onStart().
  • onDestroy(): This is the final callback you’ll receive from the OS before the activity is destroyed. You can trigger an activity’s desctruction by calling finish(), or it can be triggered by the system when the system needs to recoup memory. If your activity includes any background threads or other long-running resources, destruction could lead to a memory leak if they’re not released, so you need to remember to stop these processes here as well.

Note: You do not call any of the above callback methods directly in your own code (other than superclass invocations) — you only override them as needed in your activity subclasses. They are called by the OS when a user opens, hides or exits the activity.

So many methods to remember! In the next section, you’ll see some of these lifecycle methods in action, and then it’ll be a lot easier to remember what everything does.

Configuring an Activity

Keeping the activity lifecycle in mind, take a look at an activity in the sample project. Open MainActivity.kt, and you’ll see that the class with its onCreate() override looks like this:

class MainActivity : AppCompatActivity() {
  // 1
  private val taskList: MutableList<String> = mutableListOf()
  private val adapter by lazy { makeAdapter(taskList) }

  override fun onCreate(savedInstanceState: Bundle?) {
    // 2
    super.onCreate(savedInstanceState)
    // 3
    setContentView(R.layout.activity_main)

    // 4
    taskListView.adapter = adapter

    // 5
    taskListView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> }
  }

  // 6
  fun addTaskClicked(view: View) {

  }

  // 7
  private fun makeAdapter(list: List<String>): ArrayAdapter<String> =
      ArrayAdapter(this, android.R.layout.simple_list_item_1, list)
}

Here’s a play-by-play of what’s happening above:

  1. You initialize the activity’s properties, which include an empty mutable list of tasks and an adapter initialized using by lazy.
  2. You call onCreate() on the superclass — remember that this is (usually) the first thing you should do in a callback method. There are some advanced cases in which you may call code prior to calling the superclass.
  3. You set the content view of your activity with the corresponding layout file resource.
  4. Here you set up the adapter for taskListView. The reference to taskListView is initialized using Kotlin Android Extensions, on which you can find more info here. This replaces findViewById() calls and the need for other view-binding libraries.
  5. You add an empty OnItemClickListener() to the ListView to capture the user’s taps on individual list entries. The listener is a Kotlin lambda.
  6. An empty on-click method for the “ADD A TASK” button, designated by the activity_main.xml layout.
  7. A private function that initializes the adapter for the list view. Here you are using the Kotlin = syntax for a single-expression function.

Note: To learn more about ListViews and Adapters, refer to the Android Developer docs.

For larger data sets than you would encounter in this example, a RecyclerView and RecyclerView.ViewHolder would be recommended. See the RecyclerView docs for more information.

Your implementation follows the theory in the previous section — you’re doing the layout, adapter and click listener initialization for your activity during creation.