截止上周(本文写于2023.02.07),JetBrains推出Compose跨平台已经发布了1.3.0版本,可以说是很稳定了。很明显这也是跨平台UI的一个很好的方案。

Kotlin Multiplatform overall principle (source: [kotlinlang.org])

如果你还不了解Compose Multiplatform是什么, 也可以直接参考官网的JetBrains 网站的『长懒看』说明,一句话就是:

Fast reactive Desktop and Web UI framework for Kotlin,JetBrain公司基于Google的 先进工具套件compose,为开发者打造了一套快速响应的桌面端的web端 UI框架,可以完全使用kotlin开发。

因为和jetpack Compose绑定到一起了,相信大部分android 开发者一下子就明白:我们现在可以直接仅用kotlin就打造全平台跨平台的app了。

老哥,为啥不用flutter呢?有区别么?

其实二者还是有相当大的不同的。Kotlin跨平台技术(后文称KMP)和flutter相比,最主要的优势就是不用再学一个新的语言Dart了,直接用koltin就可以搞定,降低了学习成本。除此之外,我还发现了一个有趣的不同之处——他们处理跨平台架构的方案完全不同。

使用_Flutter_的时候,你需要先写好基础的 业务逻辑、UI逻辑,都只写一次,之后这些基础逻辑就能在不同的平台上直接运行了。你也可以继续写一些对不同平台的适配代码,来优化在特定平台运行的兼容性效果。但,无论你怎么写,真正运行到移动设备、桌面app或者是网页端的时候,你的程序还是由Flutter引擎(由Skia图像处理库构建的引擎)渲染出来而不是直接在操作系统层级渲染的。这就导致它的可移植性很好,但是UI效果并不好,和原生效果还是有些差距。

然而,使用_KMP_的话,你的业务逻辑还是只写一次,但是后面的UI界面,你需要使用kotlin对目标平台分别编写。虽然大多都可以使用kt语言,但是写法还是有区别的。比如,写android就需要用jetpack Compose框架,iOS就用swift写,桌面端就用compose Multiplatform写,等等。因此,你的app最终会有一个更接近原生的UI效果 —— 只是可移植性就差一些。

最重要的是,这两者提供了不同的方法,怎么用还是得看你的业务场景。

说实话,整体来说还是KMP听起来更好,信我!

理论到此为止!说了这么久,让你有一个初步的感受。但让我们暂时把理论放在一边,关注『怎么用』

新建一个Demo APP

还是得实操一下,要决定开发点什么东西,才能展示所有要了解的实战内容。 Flutter 也有“Hello World” 项目,从这找点儿灵感,制作一个计数器应用程序,允许用户递增和递减一个数值,并记录最新注册的操作是什么。

看起来够简单了吧

想要实现上图这个app,我们得决定好使用什么样的架构

选取架构

我们将使用 干净架构(MVVM),这是构建 GUI 应用程序(尤其是在 Android 上)的常用解决方案。 写Android的肯定是对这个架构老生常谈啦。如果你不太了解这个架构,而且感兴趣,也可以先关掉页面去研究一下~比如这个链接-Android干净架构教程

好了,到这就可以开始开工了!我们会用如下几个砖块,构建堆砌我们的app:

Domain:就是Model层,正常应该包括app的全部model,但是这个比较简单,只需要一个data class数据类。 Data:我们的抽象数据源,就是保存这个计数器app的数据的。 Use Cases:所有的用例类,就是:递增计数器、递减计数器并获取其值的方法。 Presentation:界面对应的viewModel,梳理页面操作逻辑。 Framework:数据源实现以及每个平台的用户界面。

注意:上述所有『砖块』,除了只有Framework里面的UI部分,都是可以跨平台复用的。

架构

开始写代码吧

好了,现在可以开始写代码了,我们用Intellij Idea作为示例IDE,如果你用其他惯用IDE也可以找到类似的操作方式。

先创建一个工程,从上面罗列出来的架构开始实现。一个一个类的慢慢写,直到写完全部的平台内容。 Idea这个IDE提供了一些预先构建好的KMP模型应用,我们可以直接使用。不过为了更好的学会内容,我们就先从头开始写吧。

打开IDEA,点击 File > New Project(我的是英文环境,中文类似)。

image.png

填上你自己的项目名字就可以运行了。

模块

创建好项目后,第一件事儿,就得创建一下不同的module: commonandroiddesktopweb。我们就从最基本的common开始写,写好了其他module也可以依赖它。

这时候直接在根目录右键,new module,选择compose MultiPlatform。直接就可以创建相关的模块

创建module

创建成功的效果如下:

创建完成的文件结构

修改根目录的gradle.properties文件如下:

kotlin.code.style=official
android.useAndroidX=true
kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false
android.enableJetifier=true

这个时候编译应该会很漫长,可以先等待,稍后我们会开始创建数据源集合。

数据集

因为compose的模板已经创建好了相关文件夹,但是需要思考一个问题:

不是说common模块应该是跨平台的嘛?为什么还要在里面创建desktop和android?

可以假定一个虚构的使用场景:你正在开发一个跨平台的app,但是你也需要获取到一些,不同平台特有的API。比如:获取系统版本,连接到底层的日志系统,或者是生成随机的uuid等功能。

KMP还是允许一些简单的方式去获取上面这些底层架构功能的嗯。你可以像如下操作:

// Under Common
expect fun randomUUID(): String// Under Android
import java.util.*

actual fun randomUUID() = UUID.randomUUID().toString()// And so on for all other platforms

当然了,这些复杂的底层操作在我们的简单demo中并不会用到~

回到我们的项目中。

可以注意一下我们的compose跨平台module中的 settings.gradle.kts 的文件内容

pluginManagement {
    repositories {
        google()
        gradlePluginPortal()
        mavenCentral()
        maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
    }

    plugins {
        kotlin("multiplatform").version(extra["kotlin.version"] as String)
        kotlin("android").version(extra["kotlin.version"] as String)
        id("com.android.application").version(extra["agp.version"] as String)
        id("com.android.library").version(extra["agp.version"] as String)
        id("org.jetbrains.compose").version(extra["compose.version"] as String)
    }
}

rootProject.name = "composemultidemo"

include(":android", ":desktop", ":common")

链接:https://juejin.cn/post/7197714333475553338
作者:issane

为什么要学习Kotlin?

  • Kotlin目前已经成为Android开发的官方首选语言,现在学习Kotlin正是好时机
  • 顺应潮流,现在一二线在内的各大互联网公司都在往Kotlin上转,现在学习Kotlin,更是为了未来着想。
  • 提升开发效率,因为Kotlin开发效率高于Java。

想要学习Kotlin,多一个大厂面试机会的朋友们,这里有一份《高级Kotlin强化实战》,能更快更好的帮助你从入门到精通Kotlin!扫描下方二维码免费领取

高级Kotlin强化实战

第一章 Kotlin入门教程

  • Kotlin 概述
  • Kotlin 与 Java 比较
  • 巧用 Android Studio
  • 认识 Kotlin 基本类型
  • 走进 Kotlin 的数组
  • 走进 Kotlin 的集合
  • 集合问题
  • 完整代码
  • 基础语法

在这里插入图片描述

第二章 Kotlin 实战避坑指南

  • 方法入参是常量,不可修改
  • 不要 Companion 、INSTANCE ?
  • Java 重载,在 Kotlin 中怎么巧妙过渡一下?
  • Kotlin 中的判空姿势
  • Kotlin 复写 Java 父类中的方法
  • Kotlin “狠”起来,连TODO 都不放过!
  • is、as` 中的坑
  • Kotlin 中的 Property 的理解
  • also 关键字
  • takeIf 关键字
  • takeIf 关键字
  • 单例模式的写法

在这里插入图片描述

第三章 项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐