我不是為了做一個跨平台 App 才學 KMP。
我想驗證的是兩件事:
我寫 Android 很多年,大部分時間在 platform 層:system service、HAL、SELinux、Binder。App 層用 Kotlin、Compose、Hilt、Room。對我來說,Kotlin 一直是「Android 的語言」。
這句話其實就是問題所在。Kotlin 從來不是 Android 的語言,只是我從來沒有離開過 Android 去用它。KMP 逼我第一次面對這件事。
前幾年 KMP 對 Android developer 來說是「可以玩,但不敢用」的東西。這一兩年情況改變了:Compose Multiplatform 在 iOS 上進入 stable,Room、DataStore、ViewModel、Navigation 這些 Jetpack 元件陸續出了 KMP 版本,Google 也把 KMP 列為官方推薦的 business logic 共享方案。
換句話說,一個 Android developer 熟悉的那套 stack,現在大部分都能搬到 commonMain。學習成本從「換一套工具」降到「換一個腦袋」。
寫了十幾年 Android,手上有一堆不假思索就會打出來的東西:
context.getSharedPreferences(...)
Log.d(TAG, "...")
System.currentTimeMillis()
Uri.parse(url)
File(cacheDir, "feed.json")
在 commonMain 裡,這些一個都不存在。不只 Android SDK 不在,連 java.* 都不在。commonMain 能用的只有 Kotlin stdlib 和明確宣告的 multiplatform library。
所以 KMP 的 learning curve 不是「學新 API」,而是在寫每一行 code 之前先問一個問題:
這個東西屬於誰?
粗略分三類:
| 類別 | 例子 | 去哪裡 |
|---|---|---|
| 純 Kotlin 邏輯 | data class、parsing、repository、state | commonMain |
| 平台能力 | 時間、檔案、log、locale、網路實作 | expect/actual 或 interface + 平台注入 |
| UI | list、detail、navigation | 以前是平台各自寫,現在 CMP 可以共用 |
第二類是整個系列會反覆撞到的地方。設計 platform boundary 的品味,才是 Android developer 學 KMP 時真正要長出來的東西。
我需要一個夠小、又能碰到所有層的專案。選 RSS Reader 的原因很單純:
範圍內:Feed 訂閱、文章列表、文章內容、書籤、搜尋。 範圍外:登入、雲端同步、推薦、任何 AI 功能。
AI 在這個系列是開發方法,不是產品功能。Reader 是工具,KMP 才是目的。
「請幫我生成一個 KMP Reader」然後把整包貼進 IDE,這樣我什麼都學不到。所以規則先訂好:
今天第一個 prompt 是這樣:
I'm an experienced Android developer (platform + app, Kotlin/Compose/Room/Coroutines)
starting Kotlin Multiplatform. I'll build a small RSS reader for Android + iOS
with Compose Multiplatform.
Before any code: which of my Android habits will break in commonMain,
and why? Give concrete examples of APIs I probably reach for by reflex
that don't exist there, and what the KMP-idiomatic replacement is.
明天會拿它的回答對照官方文件,看哪些說對、哪些說錯。
| Phase | 天數 | 內容 |
|---|---|---|
| 1. Why KMP / Environment | Day 1–4 | 動機、建 project、Android + iOS 第一次 build、Gradle 與 source set |
| 2. KMP Fundamentals | Day 5–10 | expect/actual、commonMain 的邊界、Coroutines/Flow 在 iOS、Ktor、serialization |
| 3. Build KMP Reader | Day 11–20 | Room KMP、Repository、ViewModel、CMP UI、Navigation、bookmark、search |
| 4. Cross-platform Engineering | Day 21–25 | iOS interop、Swift 端整合、平台差異處理、效能與 debug |
| 5. Testing / AI / Reflection | Day 26–30 | commonTest、AI 錯在哪、方法論回顧、給 Android developer 的建議 |
git init + 第一個 commitDay 2 只有一個目標:同一個 commonMain 裡的 App(),在 Android emulator 和 iOS simulator 上都跑起來。過程中會處理 Kotlin / AGP / CMP 版本、Xcode、version catalog 這些現實問題。