Learn Kotlin - Kotlin for Android Development
Series/Learn Kotlin/Episode 10
Episode 10 of 23

Learn Kotlin - Kotlin for Android Development

This episode applies Kotlin to Android development: setting up an Android project with the Gradle Kotlin DSL, Android-specific features like extension functions and ViewBinding, ViewModel and LiveData alongside coroutines, and the basics of Jetpack Compose that write UI declaratively.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Kotlin and Android have gone hand in hand since 2017. Episode 10 takes you into the world of Android: project setup with Kotlin, the features that make Android development comfortable, the ViewModel and LiveData architecture, and Jetpack Compose, which writes UI declaratively with the Kotlin DSL.

Android is Kotlin's most massive use case, so mastering it opens the door to a vast ecosystem and many opportunities. Even so, the principles you learn here — lifecycle, coroutines, and architecture — also apply to the backend in episode 11.

By the end of this episode you'll run your first Android app that displays data asynchronously using modern patterns.

Setting Up an Android Project with Kotlin

Gradle Kotlin DSL and Plugins

Modern Android projects use Gradle with the Kotlin DSL. The core configuration lives in the build.gradle.kts file:

Kotlinbuild.gradle.kts
plugins {
    id("com.android.application") version "8.5.0" apply false
    id("org.jetbrains.kotlin.android") version "2.0.0" apply false
}
 
android {
    namespace = "id.devnull.myapp"
    compileSdk = 35
    defaultConfig {
        applicationId = "id.devnull.myapp"
        minSdk = 24
        targetSdk = 35
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

namespace determines the application package, compileSdk points to the SDK API level, and jvmTarget aligns the bytecode with the JDK. An Android project is built with the command ./gradlew assembleDebug, which produces a debug APK.

Standard Project Structure

An Android project is organized in the app/src/main directory for main code, app/src/androidTest for instrumentation, and app/src/test for local unit tests. The key layout: MainActivity.kt as the entry point and AndroidManifest.xml, which declares the application components.

Android Features You'll Use Often

Extension Functions and ViewBinding

Extension functions make accessing views and parsing intents more concise. ViewBinding replaces error-prone findViewById with type-safe binding:

KotlinExtension function untuk toast
fun Context.showToast(pesan: String) {
    Toast.makeText(this, pesan, Toast.LENGTH_SHORT).show()
}

With the extension function above, calling showToast("Tersimpan") becomes available on every Context in the app. The Android ecosystem uses extension patterns like this very broadly — from dp-to-pixel conversion to accessing intent extras.

ViewModel and LiveData

A ViewModel holds UI data that survives configuration changes like screen rotation. LiveData is an observable, lifecycle-aware data holder:

KotlinViewModel dengan LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.MutableLiveData
 
class MainViewModel : ViewModel() {
    private val _jumlah = MutableLiveData(0)
    val jumlah: LiveData<Int> = _jumlah
 
    fun tambah() {
        _jumlah.value = (_jumlah.value ?: 0) + 1
    }
}

MutableLiveData is for writing inside the ViewModel, and the read-only LiveData is for the UI to use. The _jumlah.value access uses the elvis operator from episode 6 for a null initial value.

Coroutines in Android

Data calls in Android use coroutines with viewModelScope — an automatic scope that is cancelled when the ViewModel is cleared:

KotlinCoroutines di ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
 
class DataViewModel : ViewModel() {
    fun muatData() {
        viewModelScope.launch {
            val data = withContext(Dispatchers.IO) { repo.ambil() }
            tampilkan(data)
        }
    }
}

viewModelScope.launch runs a coroutine that is automatically cancelled when the ViewModel is destroyed — no more leaking background work. withContext(Dispatchers.IO) moves the I/O operation to the right thread.

Jetpack Compose Basics

Declarative UI with Kotlin

Jetpack Compose is the modern UI toolkit that writes interfaces with Kotlin functions instead of XML layouts. The interface is expressed as a @Composable function:

KotlinComposable sederhana
import androidx.compose.material3.*
 
@Composable
fun LayarSapaan(nama: String) {
    Text(text = "Halo, $nama!", style = MaterialTheme.typography.titleLarge)
}

The LayarSapaan function is invoked in the UI hierarchy and renders text. State changes trigger automatic recomposition — you no longer write findViewById and manual updates.

State and Recomposition

Compose tracks state with remember and mutableStateOf:

KotlinState di Compose
import androidx.compose.runtime.*
 
@Composable
fun Counter() {
    var jumlah by remember { mutableStateOf(0) }
    Button(onClick = { jumlah++ }) {
        Text("Klik: $jumlah")
    }
}

When jumlah changes, the composable function runs again and the UI updates. This declarative model eliminates the entire class of state-and-view synchronization bugs common in classic Android.

Running the Android App

Build and Deploy

The app is built and run with Gradle and Android Studio tooling:

Build APK dan install
./gradlew assembleDebug
./gradlew installDebug
adb logcat --pid=$(adb shell pidof -s id.devnull.myapp)

./gradlew installDebug installs the APK to the connected emulator or device, and adb logcat shows app logs at runtime. Both are part of an Android developer's daily workflow.

Closing

Episode 10 applied Kotlin to Android: project setup with the Gradle Kotlin DSL, extension functions and ViewBinding, the ViewModel and LiveData architecture with viewModelScope, and Jetpack Compose for declarative UI written with the Kotlin DSL.

The key takeaways:

  • Android configuration is written with the Gradle Kotlin DSL in build.gradle.kts.
  • Extension functions simplify working with Context and views.
  • ViewModel survives configuration changes; LiveData is lifecycle-aware.
  • viewModelScope cancels coroutines automatically when the ViewModel is cleared.
  • Compose writes UI with @Composable functions and state.
  • ./gradlew assembleDebug and installDebug are the basic workflow.

In episode 11 we'll discuss Kotlin for backend development — building a backend with Ktor, Spring Boot, or Micronaut, routing and request handling, serialization, dependency injection and configuration, and writing a REST API with middleware.

Learn Kotlin - Kotlin for Android Development | Learn Kotlin