Kotlin Multiplatform--01:项目结构基础

Kotlin Multiplatform--01:项目结构基础

引言

以下为使用 Android Studio 创建的默认 Kotlin Multiplatform 的项目结构,本章将对项目结构进行简单介绍,让读者对 Kotlin Multiplatform 项目能够有一个大概的认识。


Common Code

Common Code 是指与平台无关的代码,比如业务逻辑等。在项目结构中对应 commonMain 文件夹。需要注意的是,Common Code 不能使用任何与平台相关的 API ,比如 java.io.File 等,也不能添加任何与平台相关的依赖库。但可以使用专门为 Kotlin Multiplatform 设计的 Kotlin 库,比如 kotlinx.coroutines 等。

Targets

Target 指需要将项目编译到哪个平台上,比如 JVM, JS, Android, iOS, or Linux 等。需要注意:平台相关的代码可以调用 Common Code,但 Common Code 中不能调用平台相关的代码。在 build.gradle.kts 文件中配置,如下所示:

kotlin 复制代码
kotlin {
	androidTarget() // Declares a target that corresponds to Android phones
    iosArm64() // Declares a target that corresponds to 64-bit iPhones
    macosArm64() // Declares a target that corresponds to Modern Apple Silicon-based Macs
}

声明编译目标后,还需要在项目中新建相应的文件夹和文件,命名规则为xxxMain,还需要在里面新建名为 kotlin 的子文件夹,放该平台相关的源代码。因为我在默认项目结构上额外声明了 macosArm64 的目标,所以需要新建一个 macosMain 文件夹,如下所示:

最后在 build.gradle.kts 中的 sourceSets 中可以配置不同目标的依赖库文件,如下所示:

kotlin 复制代码
    sourceSets {
        androidMain {
            //put your multiplatform dependencies here
            implementation("xxx")
        }
        commonMain.dependencies {
            //put your multiplatform dependencies here
            implementation("xxx")
        }
        iosMain.dependencies {
            //put your multiplatform dependencies here
            implementation("xxx")
        }
        macosMain.dependencies { 
            //put your multiplatform dependencies here
            implementation("xxx")
        }
    }

Expected 和 actual

有时候我们确实需要在 Common Code 中调用平台相关的代码,并在不同的平台下有不同的表现该如何处理呢?

1.使用函数

在 CommonMain 中声明一个 except 函数,供其他 Common Code 使用:

kotlin 复制代码
package identity

class Identity(val userName: String, val processID: Long)

expect fun buildIdentity(): Identity

在不同平台中使用 actual 进行不同的实现,比如在 jvm 中进行以下实现:

kotlin 复制代码
package identity

import java.lang.System
import java.lang.ProcessHandle

actual fun buildIdentity() = Identity(
    System.getProperty("user.name") ?: "None",
    ProcessHandle.current().pid()
)

在 POSIX 系统中进行以下实现:

kotlin 复制代码
package identity

import kotlinx.cinterop.toKString
import platform.posix.getlogin
import platform.posix.getpid

actual fun buildIdentity() = Identity(
    getlogin()?.toKString() ?: "None",
    getpid().toLong()
)
2.使用接口

在 CommonMain 中声明一个 Identity 接口和 buildIdentity 函数,供其他 Common Code 使用:

kotlin 复制代码
// In the commonMain source set:
expect fun buildIdentity(): Identity

interface Identity {
    val userName: String
    val processID: Long
}

在不同平台中使用 actual 进行不同的实现,比如在 jvm 中进行以下实现:

kotlin 复制代码
// In the jvmMain source set:
actual fun buildIdentity(): Identity = JVMIdentity()

class JVMIdentity(
    override val userName: String = System.getProperty("user.name") ?: "none",
    override val processID: Long = ProcessHandle.current().pid()
) : Identity

在 POSIX 系统中进行以下实现:

kotlin 复制代码
// In the nativeMain source set:
actual fun buildIdentity(): Identity = NativeIdentity()

class NativeIdentity(
    override val userName: String = getlogin()?.toKString() ?: "None",
    override val processID: Long = getpid().toLong()
) : Identity
相关推荐
C^h22 分钟前
c++ string
开发语言·c++
raindayinrain43 分钟前
c++高性能--原子操作,无锁编程,操作顺序
开发语言·c++·性能优化
驰骋工作流1 小时前
流程时效考核的表结构:从待办时限到 WF_CH 考核结果驰骋BPM驰骋低代码低代码工作流引擎
android·低代码·rxjava
学逆向的1 小时前
C++ 合并命名空间
开发语言·c++·网络安全
Zhao-Jichao1 小时前
VS2026 打包 C++ 程序生成 EXE,借助 Installer Project 扩展工具
开发语言·c++
学逆向的2 小时前
C 局部静态变量
c语言·开发语言·网络安全
大都督会赢的2 小时前
C++第一节课
开发语言·c++
“AI国潮设计-小江”2 小时前
【AIGC实战】Python+Stable Diffusion打造“英歌舞财神”IP,解锁“马到成功”等爆款情绪营销文案设计
开发语言·人工智能·python·prompt·aigc
小王C语言3 小时前
Qt常用控件:容器类控件,标题分组框、标签页(浏览器标签)
开发语言·qt
传奇开心果编程3 小时前
【Flutter踩坑排雷】第7课:巨型 build 函数坑|全部 UI 写在同一个 build,维护难、隐性异常
android·flutter·ios·移动开发·跨平台·dart·声明式ui