Kotlin Multiplatform:共享多个目标(iOS、macOS)的实际类实现
Posted
技术标签:
【中文标题】Kotlin Multiplatform:共享多个目标(iOS、macOS)的实际类实现【英文标题】:Kotlin Multiplatform: sharing actual class implementation for multiple targets (iOS, macOS) 【发布时间】:2019-11-07 16:36:55 【问题描述】:我正在开发一个支持 JVM、ios 和 macOS 的 Kotlin/Native 多平台项目。我的设置有以下模块:
- common
- ios
- jvm
- macos
我想使用一些本机代码作为actual
类并将expected
类放入common
。但是,对于多个目标(iOS 和 macOS),实际的类实现是相同的。有没有办法设置我的源(可能在 Gradle 中),这样我就不必维护 2 个相同的实际课程副本?
【问题讨论】:
您能否扩展此“但是,每个目标(iOS、JVM 和 MacOS)的实际类实现都是相同的”。如果它们是相同的,你为什么要做期望/实际?我可以看到 iOS 和 MacOS 是一样的,但三者都是? @KevinGalligan 进行了澄清编辑。你是对的,iOS 和 macOS 是一样的,但 JVM 是不同的。 【参考方案1】:Stately 有一个相当复杂的配置。 iOS 和 Macos 共享所有相同的代码。
要构建项目,有commonMain
,nativeCommonMain
依赖于它,实际上appleMain
依赖于nativeCommonMain
。
commonMain
dependencies
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
jvmMain
dependsOn commonMain
dependencies
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
nativeCommonMain
dependsOn commonMain
appleMain
dependsOn nativeCommonMain
configure([iosX64Main, iosArm64Main, macosMain, iosArm32Main])
dependsOn appleMain
这种结构可能比您需要的更深,但我们需要一些不同的 linux 和 windows 结构。我认为 Egor 上面的回答更容易理解。
我们实际上在 Stately 中定义了多平台原子,因此您可以将它们用作灵感,或者实际上只是使用库本身。
https://github.com/touchlab/Stately
常见
expect class AtomicInt(initialValue: Int)
fun get(): Int
fun set(newValue: Int)
fun incrementAndGet(): Int
fun decrementAndGet(): Int
fun addAndGet(delta: Int): Int
fun compareAndSet(expected: Int, new: Int): Boolean
JVM
actual typealias AtomicInt = AtomicInteger
原生
actual class AtomicInt actual constructor(initialValue:Int)
private val atom = AtomicInt(initialValue)
actual fun get(): Int = atom.value
actual fun set(newValue: Int)
atom.value = newValue
actual fun incrementAndGet(): Int = atom.addAndGet(1)
actual fun decrementAndGet(): Int = atom.addAndGet(-1)
actual fun addAndGet(delta: Int): Int = atom.addAndGet(delta)
actual fun compareAndSet(expected: Int, new: Int): Boolean = atom.compareAndSet(expected, new)
【讨论】:
【参考方案2】:在Okio 中,我们声明了两个额外的源集nativeMain
和nativeTest
,并将内置的原生源集配置为依赖它们:
apply plugin: 'org.jetbrains.kotlin.multiplatform'
kotlin
iosX64()
iosArm64()
linuxX64()
macosX64()
mingwX64('winX64')
sourceSets
nativeMain
dependsOn commonMain
nativeTest
dependsOn commonTest
configure([iosX64Main, iosArm64Main, linuxX64Main, macosX64Main, winX64Main])
dependsOn nativeMain
configure([iosX64Test, iosArm64Test, linuxX64Test, macosX64Test, winX64Test])
dependsOn nativeTest
【讨论】:
【参考方案3】:如果所有三个实现都相同,只需将该代码放入common
。 expect/actual
仅用于在不同平台上不同的事物
【讨论】:
我最初说错了。我的意思是说 iOS 和 macOS 的目标实现是相同的。 JVM是不同的。我想使用一个原子整数,我可以将 AtomicInt 用于 iOS 和 macOS,但需要将 AtomicInteger 用于 JVM以上是关于Kotlin Multiplatform:共享多个目标(iOS、macOS)的实际类实现的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 和 JVM 目标之间共享 Java 代码(使用 Kotlin Multiplatform)?
Kotlin-multiplatform:如何执行 iOS 单元测试
Kotlin Multiplatform - 下一代全平台开发技术
在 Kotlin MultiPlatform 项目中未解决 iOS 依赖项
Kotlin Multiplatform 项目的 iosMain 中的 Cocoapod 依赖项,cocoapod 未解析参考