close

Compose 能應用於跨平台,主要是基於 KMM 架構,KMM 的介紹可以查看官方文檔《Get started with Kotlin Multiplatform Mobile[1]》,我們來看下 KMM 的簡單架構:

commonMain 為通用層模塊,也可以被稱為平台無關層,如果 commonMain 涉及到平台相關操作的話,則需要定義 expect 方法,讓 xxxMain 模塊去 actual 實現這個方法,這樣,在不同的平台集成 KMM 時就可以實現各自平台的效果。

從 KMM 架構可以看出,一些通用的邏輯計算完全可以丟進 commonMain 來實現,以此來達到各端只維護一份代碼的目的,也算是提效了。

KMM 架構可以實現各端的通用邏輯,那基於 KMM 的 Compose 主要目的是為了實現各平台的 ui 統一。從 compose-jb[2] 倉庫來看,目前能復用的只有 Android 和 Desktop,想支持全跨平台的話,任務依然很艱巨,我們來看下簡單的架構圖:

Android 與 Desktop 使用 jb-compose 來實現 ui 復用
web 是自己實現了一套 Compose UI 邏輯,ui 組件依賴的是 web-core-js,所以,無法與其他端復用
iOS 暫時沒有實現 Compose UI

Android 與 Desktop 能使用一份代碼來做到 ui 復用的主要原因是 jb 拷貝了一份 jetpack compose 代碼,然後實現了 jb-compose 和 compose-desktop,jb-compose 為 commonMain 層使用的通用模塊,jetpack-compose 為 Android 所集成的平台模塊,compose-desktop 為 desktop 所集成的平台模塊,:

既然是拷貝 jetpack compose 來實現一份代碼達到 ui 復用,所以,在編寫 desktop 代碼時,會發現各個 import 的組件包名都是 androidx,確實會有點奇奇怪怪,即使以後復用到了 iOS ,這塊 androidx 包名也無法被擺脫。

這裡面還有一個小細節,commonMain 明明依賴的是 jb-compose,Android 依賴的是 jetpack-compose,這兩個庫參與打包的話,難道不會發生 duplicate class 錯誤嘛?這裡可以看下 ComposePlugin 插件的 RedirectAndroidVariants 類,在 Android 項目編譯的時候,會將 jb-compose 依賴替換成 jetpack-compose。

這裡面有個小插曲,在我看 compose-jb 項目的 sample 時,看到 todoapp[3] 有 iOS 項目,難道 jb 開始支持 iOS 了?當我打開 README 時發現,咋被耍猴了:

開發跨平台應用還需要注意哪些?

既然目前可以支持 Android 和 Desktop,那麼,我們在開發界面時需要注意哪些呢?我大致列了一下:

路由、狀態、生命周期統一
圖片資源統一
多語言統一
1、路由、狀態、生命周期統一

在 Android 平台,可以使用 androidx.navigation:navigation-compose 來實現組件路由,但該組件 jb 並沒有移植到 jb-compose 中,所以,無法在兩個平台上實現復用,好在瀏覽 jb-compose 項目的 issue 時找到了一個可替代的方案 Decompose[4]。

Decompose 支持的能力有:

路由
生命周期
狀態

Decompose 支持的平台有:

android,
jvm
js (both IR and Legacy modes)
iosX64, iosArm64
tvosArm64, tvosX64
watchosArm32, watchosArm64, watchosX64
macosX64

試着跑了下 sample,效果如下:

在 jb-compose 里的 todoapp[5] sample 中,也用到了該庫:

2、圖片資源統一

為了統一兩端獲取 Drawable 資源的差異,可以將 Android 中 R.drawable 獲取資源的方式改成 resources.getIdentifier ,但如果 Android 項目有用到如 AndResGuard[6] 等資源混淆的話,則這塊代碼將會報錯,需要做 keep 處理。

如果項目有資源混淆需求的話, 建議直接定義獲取圖片的方法,如:

3、多語言統一

多語言的實現與圖片資源設置類似:

在運行 desktop 項目時遇到中文多語言亂碼問題,解決辦法是將項目編碼改成 UTF-8 即可:

資源設置可以查看我的項目:KMPCompose[7]
desktop 多語言設置:java中如何實現多語言切換[8]
總結

在整個調研和使用下來,感覺 Compose 跨平台還有很長的路要走,google 一直在埋頭發展自己的 jetpack compose,如果 jb 與 google 能雙向奔赴的話,那該有多好。

我覺得,如果有一款能直接讓客戶端的編程語言(kotlin、swift)直接實現跨端,而不是再學習一款新的語言(dart) 來實現多平台開發,那真是一件美好的事情。

Reference
[1]

Get started with Kotlin Multiplatform Mobile: https://kotlinlang.org/docs/multiplatform-mobile-getting-started.html》

[2]

compose-jb: https://github.com/JetBrains/compose-jb

[3]

todoapp: https://github.com/JetBrains/compose-jb/tree/master/examples/todoapp

[4]

Decompose: https://arkivanov.github.io/Decompose/

[5]

todoapp: https://github.com/JetBrains/compose-jb/tree/master/examples/todoapp

[6]

AndResGuard: https://github.com/shwenzhang/AndResGuard

[7]

KMPCompose: https://github.com/MRwangqi/KMPCompose

[8]

java中如何實現多語言切換: https://zhidao.baidu.com/question/58590642.html

---END---


推薦閱讀

10個問題帶你看懂 Compose 跨平台

深入理解跨平台技術的現狀與本質

Compose Multiplatform 實戰聯機小遊戲

D-KMP 架構:聲明式UI + Kotlin跨平台


交個朋友


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()