Free through lesson 3

Kotlin & Android Intro Course

From setting up through variables and null safety, functions and classes, Jetpack Compose, Navigation and ViewModel, Room and Retrofit, testing and signing. Across 50 lessons, you'll grow a memo app built with Compose into a finished state ready for Google Play (signed AAB). Every line of code and output has been run live with Kotlin 2.4.20 and JDK 21.

Curriculum

All 50 lessons are divided into 7 chapters. It's best to work through chapter 1 first, but you can also skip around to topics that interest you. Note: You can't run Kotlin and Android in the browser, so test with Android Studio or JDK 21 and Gradle (./gradlew) on your machine.

Chapter 1 — Getting Started with Kotlin (lessons 1–7)

Set up to write and run Kotlin, learn variables and types, strings and numbers, null safety, conditional branching and loops. This chapter focuses on the language alone, away from Android.

Chapter 2 — Kotlin Functions and Classes (lessons 8–14)

Functions and lambdas, classes, data classes, sealed, interfaces, scope functions and collection operations. This chapter gives you all the patterns needed to read Android code.

8

Functions (Defaults, Named Arguments, vararg)

Single-expression functions, defaults and named arguments reduce overloading, vararg, local functions, Unit vs. Nothing.

🔒 Basic
9

Lambdas and Higher-Order Functions (Trailing Lambdas and it)

Unnamed functions in { } (lambdas) and function types, pass functions to higher-order functions, trailing lambda and it, function references with ::, closures capture outer variables.

🔒 Basic
10

Classes and Properties (private set and Backing Fields)

Primary constructor and init, require, private set keeps properties read-only outside, custom getter, Kotlin 2.4's explicit backing field, by lazy.

🔒 Basic
11

Data Classes, enum, sealed (Represent Choices with Types)

enum class picks from fixed values, data class holds values (copy and destructure), sealed interface holds different info per type. when misses cause compile errors.

🔒 Basic
12

Interfaces and object (Only open Inherits)

interface promises "what you can do" with default implementations. Only classes with open can inherit, Kotlin's philosophy, object (singleton) and companion object.

🔒 Basic
13

Scope Functions and Extension Functions (let, apply, also)

Extension functions add methods like they always existed. 5 scope functions differ only in "this vs. it" and "what returns" — start with ?.let, apply, also.

🔒 Basic
14

Collection Operations (filter, groupBy, Sequence)

Immutable List, Set, Map, transform without for via filter, map, sumOf, groupBy, sortedByDescending, partition, associateBy. Sequence and Kotlin 2.4's isSorted.

🔒 Basic

Chapter 3 — Android App Foundations (lessons 15–21)

Run your first Android app, understand project structure, Activity lifecycle, resources, and manifests. Finish by peeking inside the running app with Logcat and the debugger.

15

First Android App (MainActivity and Manifest)

Build your first app from Empty Activity template, read MainActivity and manifest line by line, view in emulator and preview, test without emulator with Robolectric.

🔒 Basic
16

Project Structure (build.gradle.kts and APK Contents)

Read build.gradle.kts in full, sort compileSdk, minSdk, targetSdk, applicationId differences. Read config from code via R and BuildConfig, peek inside APK with aapt2.

🔒 Basic
17

Activity and Lifecycle (Verify Calling Order)

6 functions and 3 states called on startup, home, close, rotate. Test calling order with ActivityScenario's moveToState and recreate.

🔒 Basic
18

Configuration Changes and Saving State (rememberSaveable)

Rotate, language, theme changes recreate Activity. Line up remember and rememberSaveable counters, verify which survives with StateRestorationTester and recreate.

🔒 Basic
19

Resources and Localization (values-ja and values-night)

Put strings and colors in res/, switch with values-ja and values-night modifiers for device language and dark theme. %1$s insertions and plurals, test with Robolectric qualifiers.

🔒 Basic
20

Manifest and Intents (Explicit and Implicit)

Write Activities in manifest, exported controls if other apps can open it. Explicit intent passes data to your screen, implicit intent does sharing and opens URLs. Test with nextStartedActivity.

🔒 Basic
21

Logcat and Debugging (Log Levels and Breakpoints)

Distinguish Log.d, i, w, e by level, filter by TAG. Pass exceptions to Log.e's 3rd parameter. Test logs with ShadowLog, use breakpoints when logs don't help.

🔒 Basic

Chapter 4 — Building UI with Jetpack Compose (lessons 22–30)

Learn Composable functions, layouts, Modifier, state, lists, and theme — the full Compose UI toolkit. Finish by combining pieces to build a memo screen.

22

Composable Functions (Write UI Parts as Functions)

Functions with @Composable starting with capitals and no return become UI parts. if and for decide show and order, @Preview checks appearance, createComposeRule tests parts alone.

🔒 Basic
23

Column, Row, and Box (Arrangement and Alignment)

Column stacks vertically, Row horizontally, Box overlaps. Tell apart Arrangement (along flow direction) and Alignment (perpendicular), measure position with dp units in tests.

🔒 Basic
24

Modifier (Order Matters in Results)

Modifier applies outside-in in order. size and padding order changes 100dp to 120dp total, clickable and padding order decides if padding is clickable — measure to verify.

🔒 Basic
25

State and recomposition (Redrawn Where?)

Regular variables don't trigger redraws; mutableIntStateOf and remember do. Count recomposition, only the part reading state redraws.

🔒 Basic
26

TextField and Button (Hold Input in State)

Hold input text in state, show with value, update with onValueChange. isError and supportingText for error display, keyboard types, enabled depends on state.

🔒 Basic
27

LazyColumn (Build Only Visible Items)

Stack 100 products in LazyColumn, on 360×640dp screen only 8 rows built. key links rows to data, mutableStateListOf tells screen about add/remove.

🔒 Basic
28

Scaffold and Material Components (TopAppBar, FAB, Snackbar)

Arrange top bar, bottom button, bottom notification in Scaffold, always use innerPadding for body. Snackbar shows in coroutines, test with waitUntil.

🔒 Basic
29

Themes and Dark Mode (Read Color by Role)

Group colors in named-role ColorScheme, prepare light and dark. AppTheme adapts to device dark theme and dynamic color (Android 12+), test with qualifiers and sdk.

🔒 Basic
30

[Project] Memo Screen (Combine Chapter 4 Parts)

Combine TextField, state list, LazyColumn, Scaffold to add, delete, show zero memos. Split card row into stateless parts, test order.

🔒 Basic

Chapter 5 — Screen Navigation and Architecture (lessons 31–38)

Connect screens with Navigation, place state with ViewModel, state hoisting, and unidirectional data flow. Split the memo screen into 3 layers: screen, ViewModel, Repository.

31

Navigation (Type-Safe Routes for Screen Switching)

Navigation switches screens inside one Activity. Write destinations as @Serializable objects for type safety, NavHost maps and NavController navigates and pops. Test with TestNavHostController.

🔒 Basic
32

Screen Transitions and Arguments (toRoute and popUpTo)

Write destinations with arguments as data classes, pass with navigate(MemoDetail(id = 3)), receive with toRoute. Pass only small values like id. Clean backstack with popUpTo.

🔒 Basic
33

ViewModel (State Survives Rotation)

Move screen state to ViewModel, show read-only outside with StateFlow. Read from Compose with viewModel() and collectAsStateWithLifecycle(), Activity rebuild doesn't lose values like remember does.

🔒 Basic
34

State Hoisting (Values Down, Events Up)

Hoist state from parts to parents, receive "current value" and "call on change" function. Place state in the closest common parent, test stateless parts.

🔒 Basic
35

Unidirectional Data Flow (UiState and Events)

ViewModel holds UiState with all screen values, screen draws and reports events as functions only. copy updates, TodoRoute and TodoScreen split for separate testing.

🔒 Basic
36

SavedStateHandle (Survive Process Death)

ViewModel survives rotation but not process death. SavedStateHandle stores small values, getStateFlow flows to screen. Recreate same state in tests after process death.

🔒 Basic
37

Dependency Injection (Homemade AppContainer)

ViewModel doesn't create dependencies, receives them in constructor. interface holds contracts, AppContainer in Application and viewModelFactory pass them. Swap fakes in tests.

🔒 Basic
38

[Project] Memo App Structure (Screen, ViewModel, Repository)

Split lesson 30's memo screen to list and edit with 3 layers: screen, ViewModel, Repository. ViewModel receives id from SavedStateHandle, end-to-end app test.

🔒 Basic

Chapter 6 — Data and Communication (lessons 39–45)

Write async with coroutines and Flow, save data with Room, communicate with APIs via Retrofit. Handle communication errors and request runtime permissions.

39

Coroutines (suspend, async, Structured Concurrency)

suspend functions wait without blocking threads, async and await run together, structured concurrency cancels companions on failure, withTimeoutOrNull and withContext, runTest's fake time.

🔒 Basic
40

Flow (Values Flowing In)

flow { emit() } makes cold Flow, collect gathers it, transform with map and filter, StateFlow always holds current value, Turbine's awaitItem, debounce waits until done.

🔒 Basic
41

Room to Save Data (Entity, DAO, Database)

Handle device SQLite with Room 3. Entity (table row), DAO (read/write functions), Database (holder), KSP generates code. Test with in-memory database, verify persistence.

🔒 Basic
42

Room and Flow (Change Data, Screen Auto-Updates)

DAO returns Flow, table changes flow new results. Repository reshapes for screen, ViewModel uses stateIn and viewModelScope. Verify flowing values with Turbine.

🔒 Basic
43

Retrofit for Communication (JSON and MockWebServer)

Fetch GitHub API user info. Shape JSON as @Serializable data class, window as interface suspend function, test with MockWebServer's fake server.

🔒 Basic
44

Communication Error Handling (sealed UiState for Splits)

Model screen state as a sealed interface, exactly one case. Catch HttpException, InterruptedIOException, IOException, SerializationException, skip CancellationException, replay via MockWebServer.

🔒 Basic
45

Requesting Permissions (Ask for Notification Consent)

Notification permission needed from Android 13 — use manifest, checkSelfPermission, rememberLauncherForActivityResult for runtime permission. Protocol and channels, test with changed sdk.

🔒 Basic

Chapter 7 — Publishing Your App (lessons 46–50)

Test ViewModel and Compose UI, configure build variants and signing, prepare for Play Console submission. Finish by polishing the memo app and wrapping up.

After you finish all 50 lessons, learn the matching iOS language in the Swift Intro Course, or build the server your app connects to on the same JVM with Spring Boot Intro Course. Membership unlocks all courses.