- Tạo một project Compose Multiplatform tối giản và chạy nó trên máy thật
- Đọc được ba source set commonMain, androidMain, iosMain và biết code của mình thuộc chỗ nào
App KMP đầu tiên trên Android và iOS
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.
Máy đã sẵn sàng. Giờ đến phần đáng đợi: một màn hình do bạn viết, hiện lên trên cả điện thoại Android lẫn iPhone, từ cùng một file Kotlin.
Bài này dựng một project tối giản của riêng bạn. Nó nhỏ và chỉ có một nhiệm vụ: chứng minh máy bạn build được KMP thật.
Tạo Project Bằng KMP Wizard
Đừng tạo project bằng template "Empty Activity" của Android Studio - đó là template Android thuần. Dùng wizard chính thức của Kotlin Multiplatform:
- Mở kmp.jetbrains.com.
- Project name:
HelloKmp. Project ID:academy.dantech.hellokmp. - Tick Android và iOS. Với iOS chọn Share UI (dùng Compose Multiplatform cho cả hai, đó là trọng tâm của khóa).
- Bỏ tick Desktop và Web cho lần đầu. Thêm sau lúc nào cũng được.
- Download rồi giải nén, mở thư mục đó bằng Android Studio.
Lần mở đầu tiên Gradle sync mất 5-15 phút vì phải tải toàn bộ dependency. Thanh tiến trình chạy ở góc dưới bên phải. Đừng bấm gì thêm cho đến khi nó xong.
Vì sao dùng wizard thay vì tự tạo? Wizard sinh ra một bộ phiên bản Kotlin, Gradle, Android Gradle Plugin và Compose Multiplatform đã được kiểm tra hợp nhau. Tự ghép tay là cách nhanh nhất để gặp lỗi "không tương thích" mà người mới không đủ dữ kiện để sửa.
Ba Source Set: Chỗ Nào Là Chỗ Nào
Nhìn quen cấu trúc này thì mọi project KMP về sau đều dễ đọc.
Project có một module chia sẻ chứa toàn bộ code Kotlin của bạn, và một thư mục iosApp/ là project Xcode. Tên của module chia sẻ khác nhau tùy wizard và tùy project. Ba thư mục bên trong mới là thứ cần nhớ:
<module chia sẻ>/src/
├── commonMain/kotlin/ ← code dùng chung, 95% khóa này nằm ở đây
├── androidMain/kotlin/ ← code chỉ Android mới có
└── iosMain/kotlin/ ← code chỉ iOS mới có
| Source set | Chứa gì | Thấy được gì |
|---|---|---|
commonMain | Model, ViewModel, repository, và toàn bộ giao diện Compose | Chỉ Kotlin và thư viện multiplatform |
androidMain | Những thứ chỉ Android có: Context, Activity, quyền hệ thống | Toàn bộ Android SDK, cộng với commonMain |
iosMain | Những thứ chỉ iOS có: đường dẫn thư mục app, API của UIKit khi cần | Toàn bộ API iOS, cộng với commonMain |
Quy tắc mặc định: viết vào commonMain. Chỉ xuống androidMain hoặc iosMain khi trình biên dịch nói bạn phải làm vậy - chuyện đó hiếm, và mỗi lần xảy ra thì trình biên dịch nói rõ vì sao.
iosApp/ là project Xcode thật, viết bằng Swift, nhưng bạn gần như không đụng vào. Nó chỉ làm một việc: mở màn hình Compose của bạn ra. Xem như cái vỏ.
Chạy Trên Android
Trên thanh công cụ trên cùng, chọn run configuration của module chia sẻ, chọn thiết bị của bạn, nhấn nút Run (tam giác xanh).
Build đầu tiên chậm, 2-5 phút. App hiện ra với một nút bấm và một tấm ảnh Compose. Bấm thử để chắc chắn nó phản hồi.
Chạy Trên iOS
Chỉ làm được trên macOS. Chọn run configuration iosApp, chọn một simulator (ví dụ iPhone 16), nhấn Run.
Build iOS lần đầu chậm hơn Android khá nhiều, có thể 5-10 phút, vì Kotlin phải biên dịch sang native framework cho kiến trúc của simulator. Lần sau nhanh hơn nhiều.
Khi simulator hiện đúng màn hình bạn vừa thấy trên Android, dừng lại một nhịp và nhìn kỹ. Hai nền tảng, một file Kotlin.
Sửa Thử Một Dòng
Trong module chia sẻ, mở src/commonMain/kotlin/.../App.kt. Tìm dòng Text(...) bất kỳ, đổi nội dung thành tên bạn:
Text("Xin chào, tôi đang học KMP!")
Chạy lại trên Android. Chữ đổi. Chạy lại trên iOS. Chữ cũng đổi. Bạn vừa sửa một chỗ và giao diện của hai nền tảng cùng cập nhật.
Compose Hot Reload: từ Compose Multiplatform 1.10 trở đi, Android Studio hỗ trợ nạp lại giao diện mà không cần build lại toàn bộ khi bạn chỉ đổi phần vẽ. Nếu IDE của bạn có nút này, bật lên. Nếu chưa có, dùng Run bình thường, chậm hơn vài giây.
libs.versions.toml: Nơi Khai Báo Thư Viện
Mở gradle/libs.versions.toml. Đây là version catalog - một file duy nhất khai báo mọi thư viện và phiên bản của project. Các file build.gradle.kts chỉ tham chiếu tới nó bằng tên.
Cấu trúc gồm ba mục:
[versions]
kotlin = "2.4.10"
[libraries]
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
[plugins]
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
Rồi trong file build.gradle.kts của module chia sẻ:
commonMain.dependencies {
implementation(libs.koin.core) // dấu gạch ngang trong toml thành dấu chấm ở đây
}
Lợi ích thực tế: cần nâng phiên bản thì sửa một dòng trong [versions], không phải đi lùng khắp các file build.
Bộ phiên bản của khóa này
App mà khóa này dựng là TicTac, một game cờ ca-rô chạy trên cả hai nền tảng. Đây là bộ phiên bản nó dùng:
| Thư viện | Phiên bản |
|---|---|
| Kotlin | 2.4.10 |
| Android Gradle Plugin | 9.0.1 |
| Compose Multiplatform | 1.11.1 |
| lifecycle-viewmodel | 2.11.0-beta01 |
| Koin | 4.2.2 |
| kotlinx-serialization | 1.11.0 |
| multiplatform-settings | 1.3.0 |
| kotlinx-collections-immutable | 0.5.2 |
Những dòng có đuôi beta01 hay alpha là cố ý. Compose Multiplatform là một hệ sinh thái trẻ, và bản stable của vài thư viện trong đó tụt sau bản đang dùng được khá xa. Pin đúng bộ trên là cách chắc chắn nhất để code bạn gõ khớp với code bạn đọc.
Phiên bản mới hơn thường vẫn chạy đúng. Nếu bạn gặp lỗi lạ sau khi nâng version, hạ về đúng bộ trên là cách nhanh nhất để tách bạch "code sai" khỏi "version không hợp".
Key takeaway: commonMain là nơi bạn sống. androidMain và iosMain chỉ để giải quyết những gì thật sự khác nhau giữa hai nền tảng.