You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下Android Studio中KMM实验性@ObjCName注解编译报错求助

解决KMM跨平台注解在Windows Android Studio编译报错问题

针对你遇到的ExperimentalObjCName和ObjCName注解在Windows端无法编译的问题,核心原因是这些注解属于Kotlin/Native特有API,JVM(Android)标准库中并不包含,因此Windows端编译JVM目标时会找不到引用。以下是几种实用的解决方法:

方法一:使用Expect/Actual(推荐,KMM标准做法)

通过KMM的expect/actual机制,为不同平台提供注解的实现,共享代码中统一使用预期注解:

  1. 在commonMain中声明预期注解
    在共享模块的src/commonMain/kotlin/com/xxxx目录下创建注解文件:

    // CommonAnnotations.kt
    expect annotation class ObjCName(val swiftName: String)
    expect annotation class ExperimentalObjCName
    
  2. 在iosMain中绑定原生注解
    在src/iosMain/kotlin/com/xxxx目录下创建对应实现:

    // IosAnnotations.kt
    import kotlin.experimental.ExperimentalObjCName as NativeExperimentalObjCName
    import kotlin.native.ObjCName as NativeObjCName
    
    actual typealias ExperimentalObjCName = NativeExperimentalObjCName
    actual typealias ObjCName = NativeObjCName
    
  3. 在androidMain中定义空注解
    在src/androidMain/kotlin/com/xxxx目录下创建JVM端的空实现:

    // AndroidAnnotations.kt
    actual annotation class ExperimentalObjCName
    actual annotation class ObjCName(val swiftName: String)
    
  4. 共享代码中使用注解
    现在你可以在commonMain的业务类中直接使用注解,无需导入原生包:

    @OptIn(ExperimentalObjCName::class)
    @ObjCName(swiftName = "UtilResourceDelegate")
    class YourSharedClass {
        // 业务逻辑代码
    }
    

这种方式完全符合KMM的跨平台设计规范,Windows端编译Android目标时会使用自定义的空注解,Mac端编译iOS目标时会绑定原生注解,实现源码无缝共享。

方法二:条件编译(快速临时方案)

如果不想调整源集结构,可以直接在共享代码中使用Kotlin的平台条件编译指令:

// 根据平台判断导入或定义注解
#if !IOS
// JVM/Windows端的空注解定义
annotation class ExperimentalObjCName
annotation class ObjCName(val swiftName: String)
#else
// iOS端导入原生注解
import kotlin.experimental.ExperimentalObjCName
import kotlin.native.ObjCName
#endif

// 共享代码中正常使用注解
@OptIn(ExperimentalObjCName::class)
@ObjCName(swiftName = "UtilResourceDelegate")
class YourSharedClass {
    // 业务逻辑代码
}

注意:这种方式虽然简单,但代码可读性较差,长期维护推荐使用方法一。

额外配置说明

如果你的代码目前在src/main/java目录(非KMM标准源集),需要在共享模块的build.gradle.kts中配置标准KMM源集:

kotlin {
    android()
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    sourceSets {
        val commonMain by getting {
            kotlin.srcDirs("src/main/java") // 保留原有代码目录
        }
        val androidMain by getting {
            kotlin.srcDirs("src/androidMain/java")
        }
        val iosMain by creating {
            dependsOn(commonMain)
            kotlin.srcDirs("src/iosMain/java")
            iosX64Main.dependsOn(this)
            iosArm64Main.dependsOn(this)
            iosSimulatorArm64Main.dependsOn(this)
        }
    }
}

内容的提问来源于stack exchange,提问作者Kiwi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:05:34