3

Compose Desktop体验

 2 years ago
source link: https://youngxhui.top/2020/11/compose-desktop%E4%BD%93%E9%AA%8C/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
jetpack-compose-hero.svg

Compose

最近 JetBarin 公司发布了 Compose Desktop。是的,你没听错,就是 Google 用于Android 上的 Compose

Jetpack Compose 是用于构建原生 Android 界面的新工具包。Jetpack Compose 使用更少的代码、强大的工具和直观的 Kotlin API 简化并加快了 Android 上的界面开发。

而现在,就可以编写同样的UI层代码,然后运行到 Android 和 DeskTop 了。不难发现,这是 kotlin 一直在搞的套路,多平台共享代码。

使用了 Skia 进行硬件加速( 就是Flutter使用的 Skia ),可以与 AWT 和 Swing 进行互操作。

让我们先来一个 Hello World 试试水。

新建 Compose 项目

你可以更新到最新的idea 2020.3(目前还是beta),或者从 Github 上拉取它的模板。这里我选择使用 idea。

在 kotlin 选项中找到 JetBrains Compose ,选择 Desktop uses Kotlin。

https://island-hexo.oss-cn-beijing.aliyuncs.com/new_compose.png

创建完成后等待 gradle 依赖下载。

但是在这里会出现问题,运行是报下面的错。

org/jetbrains/kotlin/cli/common/PropertiesKt

org.jetbrains.kotlin.cli.common.PropertiesKt

Try: Run with –stacktrace option to get the stack trace. Run with –info or –debug option to get more log output. Run with –scan to get full insights.

经过排查,这是由 Gradle 和 java 14 引起的,Gradle 6.6 的版本会引起该问题,可以将gradle更改到 6.7 或者 6.5 重新进行构建。我这里修改到 6.5.1

目前 compose 的版本为 113 , 而通过 idea 创建的 版本为 63,所以更新版本。

以下为官方的 gradle.kts 配置

import org.jetbrains.compose.compose
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.4.0"
    // __UPDATE_COMPOSE_VERSION_MARKER__
    id("org.jetbrains.compose") version (System.getenv("COMPOSE_TEMPLATE_COMPOSE_VERSION") ?: "0.1.0-build113")
}


group = "me.young"
version = "1.0-SNAPSHOT"

dependencies {
    implementation(compose.desktop.currentOs)
}

compose.desktop {
    application {
        mainClass = "MainKt"

        nativeDistributions {
            targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
            packageName = "KotlinJvmComposeDesktopApplication"
        }
    }
}
repositories {
    jcenter()
    maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}

打开 main.kt, 运行 main 函数。

https://island-hexo.oss-cn-beijing.aliyuncs.com/compose%20hello.png

看样子还行,还是熟悉的界面 JavaFx , 还是熟悉的味道 Material Design 。让我们来瞅瞅代码。

fun main() = Window {
    var text by remember { mutableStateOf("Hello, World!") }

    MaterialTheme {
        Button(onClick = {
            text = "Hello, Desktop!"
        }) {
            Text(text)
        }
    }
}

通过通过点击按钮,来更改 text,从而来刷新界面。基本和其他声明式 UI ,大同小异,比如 flutter,swiftUI 等。

基本使用控件使用可以参考 androidx.compose 文档。

针对桌面做了一些扩展,比如鼠标,键盘事件,系统的原生通知,系统的托盘菜单。

https://island-hexo.oss-cn-beijing.aliyuncs.com/compose%20notify.png

具体文档可以参考官方 JetBrains/compose-jb 仓库

开发完成的应用可以直接打包为平台可执行文件。我使用的是 windows 平台。通过 packageMsi 命令打包为 exe 应用。

这里会下载 wix3

2000.jpg

2000 years later

这里可能会出现下载失败,如果下载失败,请手动到 Github 下载 wix311-binaries.zip。然后将文件命名为 wix311.zip 放在 build/wixToolset 下,重新运行 packageMsi 。

当你认为你要编译成功时, Gradle 再次报错。

������������, �����˴������MSI ��װ�����: �汾�ַ��������� MSI ���� [1.0-SNAPSHOT] �޸�����: �������¹������ô��������� “win.msi.productVersion"��https://msdn.microsoft.com/en-us/library/aa370859%28v=VS.85%29.aspx��

夺命�错,打开连接一看,好像是指定版本有问题, 微软要求版本必须按照 major.minor.build 这样的方式进行指定,而且 major 的范围是 0-255,minor的范围是 0-255,最后的 build 的范围是 0-65535 。

在 Gradle 中添加版本号。

nativeDistributions {
    targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
    packageName = "Hello World"
    version = "0.1.0"
}

更新 gradle 后重新 packageMsi。

仍旧是报错。这次是 IO 异常。

在Gradle 中添加新的配置 vendor 。

nativeDistributions {
    targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
    packageName = "Hello World"
    version = "0.1.0"
    vendor = "Example vendor"
}

经历了一番波折后终于可以打包成功。

打包后的 msi 在 build\compose\binaries\main\msi\Hello World-0.1.0.msi。

一个简单的Hello World 大小在 40 mb 左右。

目前来说,项目还有很多 bug,毕竟才 Alpha,而且官方文档也有错误。例如打包这一块,很多问题需要自己摸索。

例如中文输入法的输入的情况下报错。

Exception in thread “AWT-EventQueue-0 @coroutine#2” java.lang.NullPointerException: event.text must not be null。

图标显示问题,在我这里显示一个黑框框。

https://island-hexo.oss-cn-beijing.aliyuncs.com/icon%20problem.png

但是,jvm 上的 GUi 技术有了新的发展未尝不是一件好事,可以一处编写,多端运行。

compose-jb

JetBrains/compose-jb

androidx.compose

Jetpack Compose 基础知识


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK