Kotlin Multiplatform Android Imports 无法解决
Posted
技术标签:
【中文标题】Kotlin Multiplatform Android Imports 无法解决【英文标题】:Kotlin Multiplatform Android Imports won't resolve 【发布时间】:2019-12-31 02:48:03 【问题描述】:我创建了一个非常简单的 KMP 项目,结构如下:
-Root
--app
--gradle
--SharedCode
--src\commonMain\kotlin\actual.kt
--src\iosMain\kotlin\actual.kt
--scr\androidMain\kotlin\actual.kt
--build.gradle.kts
--native
--KotlinIOS
--iOS project (xcodeproj, etc)
一切正常,基本项目可在 Android 和 iOS 平台上运行。
但是当我尝试在我的 androidMain 目录中使用 android-specific 导入语句时,导入语句将无法解析:
import android.os.build // Android Studio can't find this
actual fun platformName(): String
return "Android"
这很奇怪,因为 iOS 包使用 iOS-specific 成功导入:
import platform.UIKit.UIDevice // This import works
actual fun platformName(): String
return UIDevice.currentDevice.systemName() +
" " + UIDevice.currentDevice.systemVersion
关于我可能需要配置什么以使我的 Android 导入工作有什么建议吗?
为了完整起见,这是我的 build.gradle.kts 文件:
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins
kotlin("multiplatform")
kotlin
//select iOS target platform depending on the Xcode environment variables
val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
::iosArm64
else
::iosX64
iOSTarget("ios")
binaries
framework
baseName = "SharedCode"
jvm("android")
sourceSets["commonMain"].dependencies
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
sourceSets["androidMain"].dependencies
implementation("org.jetbrains.kotlin:kotlin-stdlib")
val packForXcode by tasks.creating(Sync::class)
val targetDir = File(buildDir, "xcode-frameworks")
/// selecting the right configuration for the iOS
/// framework depending on the environment
/// variables set by Xcode build
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val framework = kotlin.targets
.getByName<KotlinNativeTarget>("ios")
.binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
from( framework.outputDirectory )
into(targetDir)
/// generate a helpful ./gradlew wrapper with embedded Java path
doLast
val gradlew = File(targetDir, "gradlew")
gradlew.writeText("#!/bin/bash\n"
+ "export 'JAVA_HOME=$System.getProperty("java.home")'\n"
+ "cd '$rootProject.rootDir'\n"
+ "./gradlew \$@\n")
gradlew.setExecutable(true)
tasks.getByName("build").dependsOn(packForXcode)
【问题讨论】:
FWIW,我尝试将 android 插件添加到我的构建文件中,但我认为这是不正确的,并且构建无法查找 AndroidManifest.xml 文件,在 SharedCode 目录中不可用plugins id("com.android.application") kotlin("multiplatform") android compileSdkVersion(28)
【参考方案1】:
您的 gradle 构建脚本中没有 android 所需的定义。这是一个适合我的基本 gradle 脚本:
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask
buildscript
repositories
mavenLocal()
maven("https://kotlin.bintray.com/kotlinx")
maven("https://dl.bintray.com/jetbrains/kotlin-native-dependencies")
maven("https://dl.bintray.com/kotlin/kotlin-eap")
maven("https://plugins.gradle.org/m2/")
google()
jcenter()
dependencies
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50")
classpath("com.android.tools.build:gradle:3.5.0")
classpath("co.touchlab:kotlinxcodesync:0.1.5")
plugins
id ("com.android.library") version "1.3.50"
id ("org.jetbrains.kotlin.multiplatform") version "1.3.50"
allprojects
repositories
mavenLocal()
google()
jcenter()
mavenCentral()
maven("https://dl.bintray.com/kotlin/kotlin-eap")
maven("https://kotlin.bintray.com/ktor")
maven("https://kotlin.bintray.com/kotlinx")
group = "com.example.mykmp"
version = "0.0.1"
apply(plugin = "maven-publish")
apply(plugin = "com.android.library")
apply(plugin = "kotlin-android-extensions")
android
compileSdkVersion(29)
defaultConfig
minSdkVersion(21)
targetSdkVersion(29)
kotlin
android()
val frameworkName = "mykmp"
val ios = iosX64("ios")
binaries.framework
baseName = frameworkName
sourceSets
commonMain
dependencies
implementation(kotlin("stdlib-common"))
commonTest
dependencies
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
val androidMain by getting
dependencies
implementation(kotlin("stdlib-jdk8"))
val androidTest by getting
dependencies
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
val iosMain by getting
dependencies
implementation(kotlin("stdlib"))
val iosTest by getting
dependencies
implementation(kotlin("stdlib"))
tasks.create("framework", FatFrameworkTask::class)
baseName = frameworkName
from(
ios.binaries.getFramework("DEBUG")
)
destinationDir = buildDir.resolve("xcode-frameworks")
group = "iOS frameworks"
description = "Builds a simulator only framework to build from xcode directly"
doLast
val file = File(destinationDir, "gradlew")
file.writeText(text = "#!/bin/bash\nexport JAVA_HOME=$System.getProperty("java.home")\ncd $rootProject.rootDir\n./gradlew \$@\n")
file.setExecutable(true)
tasks.getByName("build").dependsOn(packForXcode)
另外,在settings.gradle.kts
,我有这个:
pluginManagement
resolutionStrategy
eachPlugin
if (requested.id.id == "kotlin-multiplatform")
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$requested.version")
if (requested.id.id == "com.android.library")
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$requested.version")
if (requested.id.id == "kotlinx-serialization")
useModule("org.jetbrains.kotlin:kotlin-serialization:$requested.version")
否则,它可能会抱怨找不到com.android.library
。
之后我还会在 Android Studio 或 IntelliJ 上推荐 Invalidate Cache/Restart
。
希望对您有所帮助。
【讨论】:
确实解决了我的问题!你是我的英雄!谢谢!以上是关于Kotlin Multiplatform Android Imports 无法解决的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin-multiplatform:如何执行 iOS 单元测试
在 kotlin-multiplatform 上生成 UUID?
Kotlin Multiplatform 项目包含 cocoapod 依赖项
如何使用 Kotlin-Multiplatform 在 iOS 应用程序的后台线程中运行任务?