一文快速帶你瞭解 KMM 、 Compose 和 Flutter 的現狀

語言: CN / TW / HK

theme: smartblue

又到了喜聞樂見的環節,本篇主要是科普 KMM 、 Compose 和 Flutter 的最新現狀,對於 Compose 和 Flutter 大家可能並不陌生,但是對於 KMM 也許會存在疑惑,KMM 全稱 Kotlin Multiplatform Mobile ,故名思義它是用 Kotlin 實現的跨平臺框架,那為什麼今天突然會聊到它?

起因如下圖所示,今天突然有群友提及了 KMM ,並且用了“變天”的詞彙,頓時就勾起了我的興起,因為 KMM 這些年來一直“不溫不火”,可以說很多使用 Kotlin 開發的 “Androider” 對它都很陌生,難道最近它又有了什麼突破性的進展?

| | | | ----------------------------------------------------------- | ----------------------------------------------------------- |

而在求證一番之後,原來起因來自 10 月初 Android 官方宣佈 Jetpack 開始要支援 KMM 了,目前 CollectionsDataStore 已經可以通過依賴 -dev01 版本在多平臺上使用,同時 KMM 進入 Beta 版本階段

所以目前 KMM 變不了天,至少它還處於 Beta 階段,但是 Jetpack 開始支援 KMM 是個很好的訊息,這意味著 KMM 的社群支援有了官方保證

好了,介紹完起因,接下來開始進入今天的主題,什麼是 KMM 、 Compose 和 Flutter。

KMM

Kotlin Multiplatform Mobile – KMM 是基於 Kotlin 並應用在 iOS 和 Android 的一種跨平臺技術,它的特點是結合了跨平臺和原生開發協同開發的模式,如下圖所示,簡單的理解就是:從純原生開發變成了 KMM + 原生 UI 開發

使用 KMM 可以把你的業務邏輯和基建部分的能力跨平臺化,例如網路請求、資料儲存,狀態上報等模組通過 KMM 實現 Android 和 iOS 通用,例如前面介紹的 DataStore 就可以在 iOS 上支援使用。

在官方的介紹裡 KMM 的早期使用者有百度、Netflix、VMWare、Philips 等,目前收到的反饋都挺不錯,而 Beta 版本也意味著現在 KMM 已經具備了使用的基礎。

那你可能會好奇,KMM 支援 Web 嗎

聊到這個話題就很有趣,從我的角度上看,我會說 Kotlin Mutiplatform 支援,但是 KMM 不支援。

如果你安裝過 KMM 外掛和建立過 KMM 專案,你會看到 KMM 不管是從 logo 還是專案建立都只有 Android 和 iOS ,但是,Kotlin Mutiplatform 是支援 Web 的,通過 Kotlin JS 。

| | image-20221027153602062 | | ----------------------------------------------------------- | ------------------------------------------------------------ |

如果接觸 Kotlin Mutiplatform 比較早,那你那麼可能還聽說過 KMP ,KN 之類的縮寫,那它們和 KMM 又是什麼關係?簡單來說:

  • KMP 一般指的就是 Kotlin Mutiplatform ,我依稀記得 KMP 這個概念是在 Kotlin 1.2 的時候被提出,可以將Kotlin 執行到特定平臺的 JVM 和 JS 程式碼上
  • KN 一般指的是 Kotlin Native ,KN 屬於是將 Kotlin 編譯為 Native 二進位制檔案的技術,甚至可以在沒有虛擬機器的情況下執行,例如 KMM 上的 iOS 就是使用了 KN 的能力,
  • KMM 是利用了 JVM 和 KN 能力實現的針對 Android 和 iOS 平臺的 Kotlin 框架:Android(Kotlin/JVM)和 iOS (Kotlin/Naitve)

另外還有 Kotlin JS 用於 Web 平臺,所以 KMP 可以看作是大集合,而 KMM 是其中針對 Android 和 iOS 的支援,另外通過 Kotlin Native 和 Kotlin JS 也可以支援拓展到 PC 端和 Web 端

那麼到這裡你應該理解:KMM 主要是用來寫跨平臺邏輯,涉及到 UI 部分你還是需要通過原生實現,如果你從另外一個角度看,用 KMM 對於 Android 開發來說幾乎等於白送的能力,因為它只需要 Kotlin。

至少 Compose 你還需要適應下響應式開發模式。

那或者有人就問:那 KMM 這也的意義何在

事實上還真有,KMM 在 App 的基建上會很實用,比如做資料上報,崩潰統計,資料分析等等,純邏輯的跨平臺不影響 UI 部分,目前也是在這些場景上 KMM 應用較多。

另外還有人問我,KMM 可以用 Java 開發嗎? 嗯,這是個好問題,下次不要再問了。

當然,KMM 也存在一些侷限,比如使用 ViewModel 和協程如何在 iOS 上執行的問題,不過社群針對這部分也有一些第三方支援,所以對於 KMM 的未來還是值得期待。

Compose

Compose 相信大家不會陌生,其實 Compose 也可以分兩部分看待, Jetpack Compose 和 Compose Multiplatform

  • 由 Android 官方維護的 Jetpack Compose
  • 由 JetBrains 維護的 compose-jb 實現的 Compose Multiplatform

如果說 KMM 時用於實現跨平臺的業務邏輯,那麼 Compose Multiplatform 就是專注於跨平臺 UI 上的支援,那 KMM 和 Compose Multiplatform 是什麼關係呢?

從專案角度看, compose-jb 和 KMM 其實沒有關係,因為 KMM 還在 beta ,但是 Compose Multiplatform 正式已經發布接近一年的時間。

但是你要說完全沒關係顯然是不可能,畢竟 Kotlin Native 和 Kotlin JS 的能力其實在 Compose Multiplatform 裡很重要。

當然,如下圖所示,Compose Multiplatform 在跨平臺開發體驗上還是有所區別,Compose 目前是通過多個模組不同實現來支援多平臺,所以目前 Jetpack Compose 和 Compose Multiplatform 有一些“割裂”,特別是在 Web 端,想要達到 Flutter 一樣共享程式碼的比例還需要繼續努力。

PS :圖比較老,iOS 其實目前已經進入實驗階段androidx.compose.ui.main.defaultUIKitMain 相關的支援距離正式釋出可以期待。

另外 Compose Multiplatform 還有的問題就是缺少外掛社群,這其實是跨平臺領域必不可少的配置:前端有 npm 、Flutter 有 pub,你可以通過它們的中央官網搜尋你想要的庫,檢視它們的熱度,版本,相容和使用量等等資訊,設定官方認證和安全保障,但是 Maven 時代在這方面一直很弱

另一方面 Compose 的優勢也很明顯:

  • Kotlin 生態
  • Android 開發友好
  • 打包體積增長不大,程式碼壓縮比例高
  • 效能不錯,compose-android 和 compose-desktop 都使用 Skia

而隨著 Jetpack 開始支援 KMM ,那麼 Compose Multiplatform 的社群支援力度將得到進一步提升,因為變相 Compose Multiplatform 也可以支援 Jetpack

至於前面所說的“割裂”問題,目前可以看到官方也在有序推進,其中就有 desktop 的部分程式碼已經挪到了androidx 上,從這裡看或者統一的 Compose lib 並不遙遠。

PS: JetBrains 目前就已經將 Toolbox 應用通過 Compose Multiplatform 實現並且釋出使用。

Flutter

常看我文章的應該對 Flutter 更不陌生,現在 Flutter 已經是 3.3 的版本,Flutter 的特點就是跨平臺,因為它並沒有自己的平臺,同時它也是 single codebase 的跨平臺實現。

關於 Flutter 和其他框架的對比或者使用資料這裡就不多贅述,因為這方便之前我已經分享過很多,感興趣的可以參考下方連結,這裡介紹一些其他比較有意思的話題。

在 Jetbrains 的開源專案裡有一個叫 skiko 的專案,Skiko(Kotlin 的 Skia 的縮寫)是一個圖形庫,它支援 Kotlin/JVM 、Kotlin/JS 、Kotlin/Native 等相關實現,目前支援有:

  • Kotlin/JVM - Linux、Windows、macOS、Android
  • Kotlin/JS - web
  • Kotlin/Native - iOS 、macOS

如果從這個角度看 Compose Multiplatform 未來的方向會和 Flutter 很像,甚至因為 Flutter 走過更多的坑,所以 Compose Multiplatform 在對接 Skia 上可以有更多的參考。

其實未來 Linux、Windows 等平臺也完全可以脫離 JVM 通過 Kotlin/Native + Skiko 實現支援,只是維護成本會變高。

Flutter 在自建渲染引擎上其實已經越來越激進,因為直接使用 Skia 已經無法滿足日益增長的 Bug 和效能極限,所以官方開始了自研渲染引擎Impeller

因為 Flutter 團隊現在出現問題每次都要和 Skia 團隊溝通,然後等跟進,這樣的節奏太慢了,從官方的更新日誌上就可以看出目前 Flutter 的迭代速度依然很誇張。

所以這次自研的 Impeller 本質上是為了解決 Skia 需要執行時遇到的問題, Impeller 可以直接在編譯器就完成 GLSL 和 MSL ,不需要 SKSL 從而提高了效能和執行時的穩定性 ,目前優先在 iOS 平臺上開始支援 ,配合 Metal 做優化,後續如果沒問題也會同步支援 Android 和 Vulkan 。

從這個角度猜測,Flutter 在 Skia 遇到的問題 Compose Multiplatform 也很可能會遇上,而如果後續 Impeller 專案進展順利,那它或者並不會侷限在 Flutter ,也許也可以拓展支援到 Compose Multiplatform上。

其實自研發引擎並不奇怪,隨著專案的發展和深入,很多底層問題沒辦法快速推進就會反推自研,例如 Hermes 在 RN 0.7 成為預設 Engine 也是類似問題的體現,自研底層屬於是一個負責任的開源團隊的必經之路

最後

今天這篇文章的內容更多的科普性質而非技術行,主要是針對目前 KMM 、Compose 和 Flutter 的現狀做一個陳述,其實很多時候它們之間並不衝突,但是作為開發者很經常就像開頭一樣,用“對立”的角度來看 A 火了 B 就要掛,這種心態大可不必。

另外,我更喜歡“百花齊放”的氛圍,當然你也可以萬花叢中只取一朵,所以不必過於焦慮,需要什麼就用什麼就可以,技術服務於業務,就像我接觸到的很多開發,他們需要使用什麼技術並不是自己能決定的。

就比如前面那位問我 “KMM 上可以用 Java” 的那位兄弟,他是因為公司 leader 覺得 Kotlin 不成熟而不給用在 Android 上,嗯,他的 Leader 是一位後端開發。