10个问题带你了解 Compose Multiplatform 1.0

简介: 10个问题带你了解 Compose Multiplatform 1.0

近日 JetBrains 正式发布了 Compose Multiplatform 1.0 版,这标志其在生产环境中使用的时机已经成熟。相信有不少人对它还不太熟悉,本文通过下面 10 个热门问题带大家认识这一最新的跨平台技术。

FAQ

  1. 与 Jetpack Compose 的关系?
  2. 是否会取代 Flutter ?
  3. 有何技术优势?1.0是否已稳定?
  4. Android Studio 还能使用吗?
  5. 性能怎么样?
  6. 生态建设如何?
  7. 桌面应用开发是否要引入 JVM ?
  8. Web 端开发是否已经成熟?
  9. 未来是否支持 iOS ?
  10. Jetpack 是否会跨平台?

正文开始前先统一一下文中的用语:

  • compose-jb:Compose Multiplatform 简称,包含下面三者
  • compose-android:Jetpack Compose
  • compose-desktop:Compose for Desktop
  • compose-web: Compose for Web

1. 与 Jetpack Compose 的关系?

Jetpack Compose 是 Google 针对 Android 推出的新一代声明式 UI 工具包,完全基于 Kotlin 打造,天然具备了跨平台的使用基础。JetBrains 以 Jetpack Compose(后文简称 compose-android)为基础,相继发布了 compose-desktop 和 compose-web ,使 Compose 可以运行在更多不同平台。

image.png

Compose Multiplatform (后文简称 compose-jb)本质上是将 compose-desktop,compose-web 以及 compose-android 三者进行了整合,开发者可以在单个工程中使用同一套 Artifacts 开发出运行在 Android,Desktop(Windows, macOS, LInux)以及 Web 等多端的应用程序,工程中可以实现大部分代码的共享以此达到跨平台开发的目的。

image.png

所以在概念上 compose-jb 可以看做是 compose-android 的超集;在具体实现上 compose-jb 则是在 fork 了 compose-android 的源码基础上增加了对 Desktop 和 Web 侧的 API。 compose-jb 与 compose-android 同步更新,compose-jb 的 1.0 版本目前对应到 compose-android 1.1.0-beta02,因此在通用的 API 上 compose-jb 与 compose-android 时刻保持一致,不同的只是包名发生了变化,所以你可以将你的 compose-android 代码低成本地迁移到 compose-jb 工程中。

Jetpack Compose( compose-android ) Compose Multiplatform(compose-jb)
androidx.compose.runtime:runtime org.jetbrains.compose.runtime:runtime
androidx.compose.ui:ui org.jetbrains.compose.ui:ui
androidx.compose.material:material org.jetbrains.compose.material:material
androidx.compose.fundation:fundation org.jetbrains.compose.fundation:fundation

2. 是否会取代 Flutter ?

compose-jb 虽由 JetBrains 发布,但是作为 Flutter 的开发者 Google 对其也是乐见其成,因为 Compose 与 Flutter 虽然都是跨平台技术,但是两者定位不同所以不存在直接竞争关系。

Flutter 的定位就是移动端跨平台解决方案,它的一切能力建设都是围绕如何更好地“一次编写、随处运行”,首要目标就是为了降低移动应用的开发成本(虽然最近也扩展到 Desktop 以及 Desktop)。

compose-jb 的首要定位是一个声明式 UI 工具包,它的目标是通过更先进的开发范式提升 UI 开发效率。由于声明式开发思想适应性广泛,所以借助 Kotlin 成为一个跨平台框架便是水到渠成的事情。 如果说是 Flutter 成就了 Dart,那么 Kotlin 则成就了 Compose ,借助 Kotlin 近年来持续高涨的的人气,Compose 的未来也充满想象空间。

image.png

compose-jb 的受众主要有两类,首先是熟悉 Kotlin 与 Compose 的 Android 开发者,他们可以把自己的产品交付至更多平台;其次是 Kotlin 经验者,他们可以使用熟悉的语言更高效地开发包含 UI 的应用程序,像 JetBrains 这样的 IDE 公司就属于后者,他们迫切希望使用 Compose 替换 Swing 和 AWT 等基于 Java 的陈旧的技术栈,这也正是 compose-desktop 诞生的初衷。

3. 有何技术优势?1.0是否已稳定?

应用开发无非关注三件事:数据获取,状态管理,界面渲染。 JetBrains 推出 Kotlin Multiplatform Mobile (简称 KMM) 实现了数据获取部分的跨平台,而 compose-jb 将跨平台的范围进一步覆盖到状态管理甚至界面渲染(基于 Skia)。

image.png

在一个 compose-jb 工程中,逻辑层(状态管理)以及数据层的代码在几乎可以完全共享。在表现层,常用的组件和布局例如 TextButtonColumn/Row 等都可以跨越 compose-android 与 compsose-desktop 通用,此外 compose-desktop 针对桌面系统的特性还提供了专用能力,比如可以感知鼠标行为和窗口大小、创建 ScrollbarsTooltipsTray

fun main() {
   Window {
       var windowSize by remember { mutableStateOf(IntSize.Zero) }
       var windowLocation by remember { mutableStateOf(IntOffset.Zero) }
       AppWindowAmbient.current?.apply {
           events.onResize = { windowSize = it }
           events.onRelocate = { windowLocation = it }
       }
       Text(text = "Location: ${windowLocation}\nSize: ${windowSize}")
   }
}

image.png

compose-desktop 还提供了 SwingPanel 用来嵌入使用既有的 Swing 组件。compose-desktop 在能力上完全可以替代 AWT 和 Swing 等现有 UI 框架。

compose-web 为 Web 开发者提供了专门的 DOM API,针对常用的 HTML 标签实现了对应的 Composable 组件,例如 DivPA 等等 ,同时提供了 attrs 方法以 key-value 的形式设置标签属性,一些常用属性也有专属方法;另外,基于 CSS-in-JS 技术 compose-web 允许开发者基于 DSL 定义 Style 样式。

fun main() {
    renderComposable("root") {
        var platform by remember { mutableStateOf("a platform") }
        P {
            Text("Welcome to Compose for $platform! ")
            Button(attrs = { onClick { platform = "Web" } }) {
                Text("...for what?")
            }
        }
        A("https://www.jetbrains.com/lp/compose-web") {
            Text("Learn more!")
        }
    }
}

image.png

compose-web 拥有 HTML 或 JSX 那样的结构化的表现力,同时有具备了响应式状态管理能力,在 compose-jb 中还可以与 Desktop 和 Android 侧共享逻辑层代码。

稳定性方面,compose-jb 的大部分代码来自 Jetpack Compose,在 Android 端已经有上千款 App 接入,这足以保证其在 Android 端上的稳定性。

image.png

JetBrains 在几个月之前就将 Toolbox 应用从 C++ 和 Electron 迁移到了 compose-jb,并一直平稳运行,服务着超过 100 万的月活用户,常规的 UI 开发得到了检验。但是一些复杂功能可能还不够稳定,目前还有不少 issue 有待解决。

4. Android Studio 还能使用吗?

compose-jb 1.0 可以运行在 IntelliJ IDEA 2021.1 之后的版本中,IDEA 专门为其提供了工程向导和项目模板,指导开发者快速新建一个 compose-jb 项目。

image.png

开发者还可以通过插件市场下载 compose-desktop 侧的专用预览插件,在 Desktop 端实时预览添加 @Preview 的 Composalbe,提高开发效率。

image.png

Andorid Studio 作为 IntelliJ 平台下的 IDE ,自然也可以用于 compose-jb 项目的开发( IDEA 2021.1 对应 Android Studio Bumblebee 之后的版本)。AS 自带 Andoid 侧的预览能力,可以实时预览 UI 代码效果。此外 AS 对 Compose 的代码提示也更友好,比如非法调用 @Composable 函数时, IDE 会标红提示错误,而 IDEA 则只能在编译时发现错误。

5. 性能怎么样?

compose-android 和 compose-desktop 都使用 Skia 这一开源图形库进行渲染。Skia 在 Chrome,Flutter 等多个项目中广泛使用,性能方面得到了验证。Skia 还能支持平台特有的硬件加速技术,例如 DirectX,Metal 和 OpenGL 等,compose-jb 为没有硬件加速的设备也提供了优化的软件渲染方案。曾经有人将 compose-desktop 与 JavaFX 进行过实际对比测试,在通常情况下两者渲染性能相当,尽在极端情况下会略逊于 JavaFX,不过已经足够优秀了。

dev.to/gz_k/jetpac…

Web 侧 compose-jb 会通过 Kotlin/JS 编译器将代码仍然编译成 JS 代码在浏览器运行,所以理论上与传统的 Web 开发方式在性能上没有区别,由于 CSS-in-JS 实现都是在运行时生成 CSS,仅仅在这一点上相对于直接使用 CSS 前端项目可能略有一点性能损耗。

而在逻辑代码由于使用 Kotlin 作为开发语言,代码的执行效率要明显优于基于 Node 的 Electron 等同类跨平台框架,Kotlin/JVM 也保证了在桌面侧至少有与 Java 同样的运行时性能。

6. 生态建设如何?

compose-jb 依托 Kotin Multiplatform 的丰富类库,满足各种层面的能力开发,比如在架构、网络、数据存储等各方面都有不少优秀的的解决方案,一些代表性的项目如下:

Category Library Description
Architecture Decompose Kotlin Multiplatform lifecycle-aware business logic components (aka BLoCs) with routing functionality and pluggable UI (Jetpack Compose, SwiftUI, JS React, etc.), inspired by Badoos RIBs fork of the Uber RIBs framework
MVIKotlin Extendable MVI framework for Kotlin Multiplatform with powerful debugging tools (logging and time travel), inspired by Badoo MVICore library
redux-kotlin Redux implementation for Kotlin (supports multiplatform JVM, native, JS, WASM)
Network Ktor Framework for quickly creating connected applications in Kotlin with minimal effort
rsocket-kotlin RSocket Kotlin multi-platform implementation
Storage sqldelight SQLDelight - Generates typesafe Kotlin APIs from SQL
Kodein-DB Multiplatform NoSQL database
multiplatform-settings A Kotlin Multiplatform library for saving simple key-value data
Utils & Others Reaktive Kotlin multi-platform implementation of Reactive Extensions
koin A pragmatic lightweight dependency injection framework for Kotlin
kotlinx-datetime KotlinX multiplatform date/time library
kotlin-logging Lightweight logging framework for Kotlin. A convenient and performant logging library wrapping slf4j with Kotlin extensions

More libraries:libs.kmp.icerock.dev/

7. 桌面应用开发是否要引入 JVM ?

compose-jb 在桌面端需要支持 Windows,macOS,Linux 等多套操作系统,基于 Kotlin/Native 的实现成本较高,因此现阶段 compose-desktop 仍然依赖 Kotlin/JVM 编译成 Java 字节码后再发布到各桌面系统。

compose-desktop 提供了专用的 Gradle 插件可以基于 jpackage 将 JVM 一同打包进各种格式的安装包,例如 Mac 的 dmg, Windows 的 msi,exe 以及 Linnux 的 deb 等,使用者无需额外安装 JDK ,可以像二进制程序一样开箱即用,此外还通过使用 jlink 技术只对 Java 模块的最小依赖进行打包以最大限度降低包体积。

$ ./gradlew package
> Task :packageDmg
WARNING: Using incubator modules: jdk.incubator.jpackage
The distribution is written to build/compose/binaries/main/dmg/DesktopApp-1.0.0.dmg
BUILD SUCCESSFUL in 11s
5 actionable tasks: 3 executed, 2 up-to-date

目前对 Kotlin/Native 编译器的适配工作也在进行中,未来 compose-desktop 有望通过切换到 Kotlin/Native 进一步提高应用的执行速度。

8. Web 端开发是否已经成熟?

compose-jb 中整合 compose-web 的最主要意义是帮助 Kotlin 开发者扩大应用的发布场景。如果你已经有一个 compose-desktop 或者 compose-android 项目,那么基于 compose-web 可以把产品快速发布到 Web 端,并共享其中大部分的逻辑代码。

compose-web 提供的声明式 DOM API 相对于 HTML+JS+CSS 这一传统技术栈在开发范式上更加先进。但如果你已经有 React 等前端框架的使用经验那么此项优势就不存在了。而且 compose-web 在建设速度上要落后于 compose-desktop,部分 HTML 标签以及属性还缺少对应的 DSL 实现,所以从单纯开发一个前端应用的角度看,如果你对 Kolin 没有执念的话,更推荐使用 React 等已有的成熟框架。

即使从跨平台的角度看, desktop-web 也仍然有改善空间。desktop-web 在 API 设计上尊重原有的 HTML 开发习惯,这也导致其 DSL 上与 compose-android 和 compose-desktop 的差异较大,不利于 UI 代码的共享。据悉 JetBrains 团队已经着手开发与其他两端风格一致的 DSL ,届时可以通过 HTML5 Canvas 实现 UI 统一绘制,提高跨平台的开发体验。

9. 未来是否支持 iOS?

compose-jb 目前没有对 iOS 端的支持,这是其成长为主流跨平台框架道路上的一个严重阻碍,因此可以大胆猜想 compose-jb 在未来一定会增加对 iOS 的支持,而且有迹象表明 JetBrains 已经偷偷开始了这方面工作。

image.png

有人就曾经在 compose-jb 工程中也发现过针对 iOS 的开发分支,而且 compose-ui 依赖的 Skiko 库也已经增加了对 iOS 的支持,理论上完全可以实现 iOS 侧渲染。由于 iOS 不使用 Kotlin/JVM ,所以在 Kotlin/Native 编译器以及 iOS 工具链等方面存在大量适配工作,毕竟 KMM 本身也还处于 alpha 阶段,iOS 端的开发体验还不理想,这可能就是 compose-ios 迟迟未发布的原因,但是未来是可以期待的。

那么在 compose-ios 还未出现的当下,如果你的应用有发布到 iOS 侧的需求,作为一个过渡方案可以先借助 KMM 推荐 D-KMP 架构实现逻辑层和数据层的代码共享,UI 侧现阶段可以使用 Swift-UI 等平台语言进行开发,等待 compose-ios 真正到来时再对 UI 代码进行迁移。

github.com/dbaroncelli…

image.png

10. Jetpack 是否会跨平台?

很多 Android 开发者习惯于 Compose 搭配 Android 的 Jetpack 系列组件一同使用,所以当一个 compose-android 项目被迁移到 compose-jb 时,不少人希望有对应的 KMP 版本 Jetpack 库可供使用。

在前不久 Android Dev Summit 上 Andorid Jetpack 团队就这个问题进行了回答,答案是暂时没有相关计划。

www.youtube.com/watch?v=Qre…

首先 Jetpack 中一些重度依赖 Andorid 平台特性的组件不适合发布 KMP 版本,而一些平台无关的组件例如 Hilt,Room 等,虽然具备 KMP 化的基础但仍然会谨慎启动,因为当前首要任务还是保证其在 Android 端的稳定使用。虽然当前没有计划但是 Jetpack 团队也表示了未来会尝试对部分 Jetpack 库进行 KMP 改造,他们很乐于帮助开发者能更低成本地完成项目向 KMP 的迁移。

对于开发者来说,如果你的项目近期有跨平台的需求,那么在技术选型上就要避免过度依赖 Jetpack ,而要像 KMP 的 Library 倾向。比如在逻辑层优先使用 Flow 而非 LiveData 等;在数据层也可以考虑使用 SQLDelight 替代 Room 。

目录
相关文章
|
XML 编译器 Android开发
Kotlin DSL 实战:像 Compose 一样写代码
Kotlin DSL 实战:像 Compose 一样写代码
522 0
|
XML IDE Java
Android gradle.properties 基础使用和常规配置
Gradle 是一个开源构建自动化工具,其设计足够灵活,可以构建几乎任何类型的软件。
|
JavaScript 前端开发 Java
基于SpringBoot+Vue实现前后端交互功能(详解Vue框架机制)
基于SpringBoot+Vue实现前后端交互功能(详解Vue框架机制)
|
5月前
|
Oracle Java 关系型数据库
SpringBoot从0-1集成Graalvm
本文介绍如何使用GraalVM将SpringBoot应用打包为原生可执行文件并构建Docker镜像。相比传统JAR包,原生镜像启动更快、体积更小,提升部署效率,适合现代云原生环境。
876 10
|
移动开发 定位技术 Android开发
「揭秘高效App的秘密武器」:Kotlin Flow携手ViewModel,打造极致响应式UI体验,你不可不知的技术革新!
【9月更文挑战第12天】随着移动开发领域对响应式编程的需求增加,管理应用程序状态变得至关重要。Jetpack Compose 和 Kotlin Flow 的组合提供了一种优雅的方式处理 UI 状态变化,简化了状态管理。本文探讨如何利用 Kotlin Flow 增强 ViewModel 功能,构建简洁强大的响应式 UI。
356 3
|
Cloud Native Java C++
Springboot3新特性:开发第一个 GraalVM 本机应用程序(完整教程)
文章介绍如何在Spring Boot 3中利用GraalVM将Java应用程序编译成独立的本机二进制文件,从而提高启动速度、减少内存占用,并实现不依赖JVM运行。
2194 1
Springboot3新特性:开发第一个 GraalVM 本机应用程序(完整教程)
|
11月前
|
存储 资源调度
在 Pinia 中如何实现状态持久化?
在 Pinia 中如何实现状态持久化?
2156 57
|
存储 监控 数据可视化
常见的分布式定时任务调度框架
分布式定时任务调度框架用于在分布式系统中管理和调度定时任务,确保任务按预定时间和频率执行。其核心概念包括Job(任务)、Trigger(触发器)、Executor(执行器)和Scheduler(调度器)。这类框架应具备任务管理、任务监控、良好的可扩展性和高可用性等功能。常用的Java生态中的分布式任务调度框架有Quartz Scheduler、ElasticJob和XXL-JOB。
4912 66
|
Java Spring 容器
详解java参数校验之:顺序校验、自定义校验、分组校验(@Validated @GroupSequence)
详解java参数校验之:顺序校验、自定义校验、分组校验(@Validated @GroupSequence)
|
Java UED Spring
Springboot通过SSE实现实时消息返回
通过Spring Boot实现SSE,可以简单高效地将实时消息推送给客户端。虽然SSE有其限制,但对于许多实时消息推送场景而言,它提供了一种简洁而强大的解决方案。在实际开发中,根据具体需求选择合适的技术,可以提高系统的性能和用户体验。希望本文能帮助你深入理解Spring Boot中SSE的实现和应用。
6736 1