Android Kotlin — Cheat Sheet

Tags: android, kotlin, mobile, coroutines, jetpack, flow, mvvm

Level: intermediate

TL;DR: Core Kotlin features for Android development, focusing on concurrency (Coroutines/Flow), UI state management, and modern architecture patterns.

Key concepts

-

Null safety: variables are non-nullable by default. Use ? for nullable types and safe calls.

-

Data classes: automatically generate equals(), hashCode(), toString(), and copy() methods for state representation.

-

Coroutines: lightweight threads for asynchronous programming managed via Dispatchers (Main, IO, Default).

-

Flow: cold asynchronous data streams. StateFlow and SharedFlow are hot streams used for state and events.

-

Scope functions: let, run, with, apply, also. Execute code blocks within the context of an object.

-

Extension functions: add new functions to existing classes without inheritance.

-

Sealed classes: restricted class hierarchies, ideal for representing finite states like UI states.

-

MVVM pattern: Model-View-ViewModel is the recommended architecture. ViewModel survives configuration changes.

Typical questions and ready answers

-

Q: What is the difference between val and var?R: val is read-only (immutable reference), while var is mutable and can be reassigned.

-

Q: How do Coroutines differ from standard threads?R: Coroutines are cooperative and lightweight. I can run thousands of them concurrently without exhausting system memory.

-

Q: What is the difference between lateinit and lazy?R: lateinit is for var variables initialized later. lazy is for val variables initialized upon first access.

-

Q: How does StateFlow differ from LiveData?R: StateFlow requires an initial value and supports Kotlin Flow operators. LiveData is lifecycle-aware by default.

Pitfalls and common mistakes

-

Memory leaks from passing Activity context to long-running Coroutines or ViewModels.

-

Using GlobalScope for coroutines instead of lifecycle-aware scopes like viewModelScope or lifecycleScope.

-

Overusing the !! operator instead of safe calls (?.) or Elvis operator (?:), causing runtime crashes.

-

Performing heavy I/O operations on Dispatchers.Main instead of switching to Dispatchers.IO.

Snippets and commands

// Flow collection in UI (Compose)
val uiState by viewModel.uiState.collectAsStateWithLifecycle()

// Launching a coroutine in ViewModel
viewModelScope.launch(Dispatchers.IO) {
    val data = repository.fetchData()
    _uiState.update { it.copy(data = data) }
}

// Extension function example
fun View.visible() {
    this.visibility = View.VISIBLE
}

To review

-

[ ] Advanced Flow operators (flatMapLatest, combine, zip)

-

[ ] Dependency Injection (Hilt/Dagger) setup in Kotlin

-

[ ] Compose performance optimization and recomposition loops

Jarvis Interviews
Jarvis