# Kotlin Mobile 101

> Học trọn bộ nền tảng: Kotlin + Compose Multiplatform, MVVM + Koin + State Machine để build 1 mobile app chạy trên cả Android và iOS.

- URL: https://dantech.academy/courses/kotlin-mobile-101
- Instructor: Dan Tech
- Chương trình học: 22 bài học
- English: https://dantech.academy/en/courses/kotlin-mobile-101.md

Khóa nhập môn Kotlin Multiplatform: nền tảng Kotlin và Compose Multiplatform, 3 tầng MVVM, inject dependency bằng Koin, điều hướng bằng screen state machine và lưu dữ liệu local. Bạn đọc và sửa một Kotlin Multiplatform app hoàn chỉnh có sẵn, chạy trên máy thật, kèm bộ unit test chạy trong vài giây, và giải thích được vì sao từng dòng nằm ở đó.

## Yêu cầu

- Người mới
- Laptop (macOS nếu muốn chạy iOS)
- 1h/ngày

## Kỹ năng

- Kotlin essentials
- Compose Multiplatform
- MVVM Architecture
- Koin DI
- State machine
- Local persistence

## Chương trình học

Gợi ý cho AI agent: mỗi bài học có bản Markdown ở URL của bài cộng `.md`. Bài miễn phí trả về toàn bộ nội dung, bài dành cho học viên trả về mục tiêu và dàn ý.

### Setup & App Đầu Tiên

toolchain KMP sạch, app chạy trên cả Android và iOS, Git checkpoint và AI pair với rules file.

- [Android Studio, JDK và KMP plugin](https://dantech.academy/courses/kotlin-mobile-101/00-setup-first-run/lesson-01-install-android-studio.md) (miễn phí): JDK 17+, Android Studio stable, plugin Kotlin Multiplatform, Xcode nếu bạn dùng macOS, và kdoctor để kiểm tra máy.
- [App KMP đầu tiên trên Android và iOS](https://dantech.academy/courses/kotlin-mobile-101/00-setup-first-run/lesson-02-first-app-on-device.md) (miễn phí): Tạo một project Compose Multiplatform tối giản, chạy nó trên máy thật, và đọc được ba source set commonMain / androidMain / iosMain.
- [Clone TicTac, Git checkpoint và rules file cho AI](https://dantech.academy/courses/kotlin-mobile-101/00-setup-first-run/lesson-03-git-checkpoints-ai-pair.md) (miễn phí): Clone repo TicTac, chạy nó trên Android, tạo branch cá nhân, và viết rules file pin đúng stack để AI không gợi ý code Android thuần.

### Kotlin Essentials

null safety, lambda, data class và sealed interface, collections, coroutines và Flow.

- [Null safety, biến và hàm](https://dantech.academy/courses/kotlin-mobile-101/01-kotlin-essentials/lesson-01-null-safety-and-functions.md): val và var, kiểu nullable, các operator ?. ?: !!, tham số mặc định và tham số có tên, lambda, extension function - đọc trên code thật của TicTac.
- [Data class, enum và sealed interface](https://dantech.academy/courses/kotlin-mobile-101/01-kotlin-essentials/lesson-02-data-and-sealed-classes.md): data class cho giá trị bất biến, enum cho tập lựa chọn cố định, sealed interface cho trạng thái nhiều nhánh, when exhaustive - đọc trên code thật của TicTac.
- [Collections, coroutines và StateFlow](https://dantech.academy/courses/kotlin-mobile-101/01-kotlin-essentials/lesson-03-collections-and-coroutines.md): filter, map, count, any/none/all, take; suspend và coroutine scope cho việc mất thời gian; StateFlow cho dữ liệu đổi theo thời gian.

### Compose Fundamentals

composable, layout, Modifier, state và recomposition, lưới bàn cờ và hàng chip lựa chọn.

- [Composable, layout và Modifier](https://dantech.academy/courses/kotlin-mobile-101/02-compose-essentials/lesson-01-composables-and-layout.md): Composable Function, ba khối layout Column Row Box, thứ tự Modifier quyết định kết quả, và cách TicTac dựng giao diện dùng chung cho Android lẫn iOS.
- [State, recomposition và state hoisting](https://dantech.academy/courses/kotlin-mobile-101/02-compose-essentials/lesson-02-state-and-recomposition.md): Recomposition, remember và khóa của nó, collectAsStateWithLifecycle, và state hoisting đẩy tới tận cùng như TicTac làm.
- [Lưới và lựa chọn](https://dantech.academy/courses/kotlin-mobile-101/02-compose-essentials/lesson-03-grid-and-selection.md): Dựng lưới bàn cờ bằng Column, Row và repeat; dựng hàng chip chọn từ enum.entries; và điều kiện để phải đổi sang lazy layout.

### MVVM

ba tầng Model, ViewModel, View - ranh giới kiểm được bằng grep, và state suy ra thay vì lưu trùng.

- [MVVM và phụ thuộc một chiều](https://dantech.academy/courses/kotlin-mobile-101/03-mvvm/lesson-01-why-mvvm-and-three-layers.md): Ba giới hạn của state trong composable, trách nhiệm của Model, ViewModel, View, và cách chứng minh ranh giới bằng chính cấu trúc package của TicTac.
- [Model và state riêng cho từng màn hình](https://dantech.academy/courses/kotlin-mobile-101/03-mvvm/lesson-02-model-and-ui-state.md): Sealed interface thay cho cờ boolean rời rạc, mỗi màn hình một state chỉ chứa thứ nó vẽ, và property get() suy ra thay vì lưu trùng dữ liệu.
- [ViewModel với StateFlow](https://dantech.academy/courses/kotlin-mobile-101/03-mvvm/lesson-03-viewmodel-with-stateflow.md): Cặp _round / round, init{} nạp dữ liệu một lần, Channel CONFLATED gộp lệnh lưu, và hủy timer khi rời màn hình đang chơi.

### Koin Và Dependency Injection

Koin module và hai vòng đời, bind theo contract, và một lệnh gradle kiểm cả đồ thị.

- [Koin căn bản: single và viewModel](https://dantech.academy/courses/kotlin-mobile-101/04-koin-di/lesson-01-koin-basics.md): Vấn đề mà dependency injection giải, hai vòng đời single và viewModel, và vì sao initKoin() phải gọi ngoài composition.
- [Dependency injection: get(), bind theo contract và call site](https://dantech.academy/courses/kotlin-mobile-101/04-koin-di/lesson-02-injecting-dependencies.md): get() để Koin tự lắp đồ thị, bind theo contract để không ai biết lớp cụ thể, và koinViewModel() ở đúng một chỗ trong cây Compose.
- [Vòng đời và test đồ thị](https://dantech.academy/courses/kotlin-mobile-101/04-koin-di/lesson-03-scoping-and-testing.md): Thay kho thật bằng MapSettings trong test, resolve từng nút của đồ thị, và assertSame để chứng minh single thật sự dùng chung.

### Máy Trạng Thái Màn Hình

state machine năm màn thay cho thư viện điều hướng, một ViewModel dùng chung, và expect/actual nối nút back hệ thống.

- [Điều hướng bằng screen state machine](https://dantech.academy/courses/kotlin-mobile-101/05-navigation/lesson-01-screen-state-machine.md): enum Screen cộng một when trong AppHost thay cho thư viện điều hướng, và ba điều kiện để biết khi nào mô hình phẳng này không còn đủ.
- [Mỗi màn một ViewModel, dữ liệu dùng chung một chỗ](https://dantech.academy/courses/kotlin-mobile-101/05-navigation/lesson-02-one-viewmodel-five-screens.md): ViewModel riêng cho từng màn hình, dữ liệu dùng chung nằm trong các single của Koin thay cho tham số truyền qua route, và mặt trái: ván đang chơi vẫn sống khi bạn đã sang màn khác.
- [expect/actual và nút back của hệ thống](https://dantech.academy/courses/kotlin-mobile-101/05-navigation/lesson-03-system-back-handler.md): Một khai báo chung, mỗi nền tảng một hiện thực: nối nút back Android vào state machine, và hai bộ expect/actual khác trong repo.

### Ráp App Hoàn Chỉnh

lưu key-value và JSON không crash khi dữ liệu hỏng, ráp năm màn, theme thủ công, debug và bản build cài được.

- [Lưu dữ liệu bằng key-value](https://dantech.academy/courses/kotlin-mobile-101/06-full-app/lesson-01-key-value-persistence.md): multiplatform-settings, khóa rời rạc thay vì một blob, đọc có giá trị dự phòng riêng từng khóa, và runCatching bọc API đồng bộ dễ vỡ.
- [JSON cho danh sách, và fail-soft](https://dantech.academy/courses/kotlin-mobile-101/06-full-app/lesson-02-json-for-lists.md): @Serializable, serializer tự viết cho ImmutableList, mô hình hóa kết quả đọc bằng sealed interface HistoryRead (Ok/Empty/Corrupt), lọc bản ghi hỏng, cắt về giới hạn, và cache tránh mã hóa lại khi không cần.
- [Ráp app: từ điểm khởi động tới màn hình](https://dantech.academy/courses/kotlin-mobile-101/06-full-app/lesson-03-assemble-the-app.md): App.kt làm điểm vào chung, AppHost làm gốc composable, và hai vỏ nền tảng Android với iOS mỏng nhất có thể.
- [Theme thủ công, và đưa app ra máy thật](https://dantech.academy/courses/kotlin-mobile-101/06-full-app/lesson-04-theme-debug-and-ship.md): Palette làm bảng token, dark mode thủ công cố ý bỏ qua theme hệ thống, màu Unspecified để lỗi to tiếng, và lệnh build cho cả hai nền tảng.
