前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Compose 跨平台现状

Compose 跨平台现状

作者头像
codelang
发布2022-11-30 14:40:03
3.2K0
发布2022-11-30 14:40:03
举报
文章被收录于专栏:codelang

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 扣浪 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开发跨平台应用还需要注意哪些?
    • 1、路由、状态、生命周期统一
      • 2、图片资源统一
        • 3、多语言统一
        • 总结
          • Reference
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档