如何让 Kotlin Multiplatform 使用 Android Studio 的项目视图?

How to make Kotlin Multiplatform work with Android Studio's project view?

我正在尝试在 Android studio 中构建一个多平台库模块的模板,它可以与其他正常的 Android 库和应用程序模块无缝互操作。我发现在编译、运行 和发布人工制品方面使多平台 Android 项目在技术上很容易工作,但我似乎无法解决的一个问题是让源集显示在 Android 项目文件窗格视图中正确显示。

所以你可以在这里的Project视图中看到,sources分为android,native和common目录以及各自的test目录,总共有六个源码目录:

在 Android 项目视图中,这是由构建目标而不是源文件目录呈现的,因此这个 'typing-sdk' 模块示例共有 10 个不同的子模块。您会注意到 androidMain 和 androidTest 不在其中:它们的源代码不是作为子模块呈现,而是位于内联 kotlin 目录下;你可以分别看到主包和测试包com.demo.typing。

每个单独的构建目标都有自己的子模块,这有点烦人,但在实践中,人们实际上永远不需要使用其中的一些子模块,例如 'iosArm64Test'。尽管如此,我可以忍受冗余的子模块。 这里的核心问题是每个子模块都填充了错误的源文件。

因此,在文件结构中,普通集和本地集都有自己的源文件,正如您在此处看到的:

在 Android 项目视图中,每个子模块都包含 Android 源!?

这是 Android Studio 如何与 Kotlin Multiplatform Gradle 插件互操作的错误,或者我编写的 Gradle 构建文件有问题,就是这个(使用 Gradle 7.1):

plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.6.10'
    id 'com.android.library' version '7.0.4'
}

allprojects {
    group = 'typing'
    version = '1.0'
    sourceCompatibility = '1.8'

    repositories {
        mavenCentral()
        google()
    }
}

kotlin {
    android()
    ios()

    sourceSets {
        commonMain
        commonTest
        androidMain {
            dependsOn(commonMain)
        }
        androidAndroidTestRelease
        androidTest {
            dependsOn(commonTest)
            dependsOn(androidAndroidTestRelease)
        }
        nativeMain {
            dependsOn(commonMain)
        }
        nativeTest {
            dependsOn(commonTest)
        }
        iosMain {
            dependsOn(nativeMain)
            iosX64Main.dependsOn(it)
            iosArm64Main.dependsOn(it)
        }
        iosTest {
            dependsOn(nativeTest)
            iosX64Test.dependsOn(it)
            iosArm64Test.dependsOn(it)
        }
    }
}

android {
    compileSdk 31
    defaultConfig {
        minSdk 23
        targetSdk 30
    }
}

我注意到大多数源代码示例已经在使用 Kotlin DSL,这是更可取的,但情况迫使我在这里使用 Groovy。在我的另一个项目是 Kotlin DSL,使用早期版本的 Gradle (7.0.2) Android Gradle 插件 (7.0.2) 和 Kotlin (1.5.20), Android 项目视图以不同的方式呈现,虽然仍然存在很大缺陷,但在每个构建目标模块下列出 Android 源并不是灾难性的错误。在该项目的 Android 块中,您有 com.android.library 插件的第二个源集定义:

android {
    compileSdk = 31
    defaultConfig {
        minSdk = 23
        targetSdk = 30

        consumerProguardFiles("proguard-rules.pro")
    }
    sourceSets.all {
        java.srcDirs(file("src/android${name.capitalize()}/kotlin"))
        res.srcDirs(file("src/android${name.capitalize()}/res"))
        resources.srcDirs(file("src/android${name.capitalize()}/resources"))
        manifest.srcFile(file("src/android${name.capitalize()}/AndroidManifest.xml"))
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

我不知道如何直接将其翻译成 Groovy,但根据 Android 文档,可以这样写:

android {
    compileSdk 31
    defaultConfig {
        minSdk 23
        targetSdk 30
    }
    sourceSets {
        main {
            java.srcDirs = ['src/androidMain/kotlin']
            manifest.srcFile 'src/androidMain/AndroidManifest.xml'
        }
        test {
            java.srcDirs = ['src/androidTest/kotlin']
        }
        androidTest {
            setRoot 'src/androidTest/kotlin'
        }
    }
}

不幸的是,这不能解决问题。如果没有人能向我展示不会在 Android Studio 中创建可怕和损坏的源文件视图的可行 Gradle 脚本,我会将其作为错误提交给 JetBrains。

建议 IDE 在进行多平台开发时使用 IntellIJ。

Android Studio 用于更多 Android 具体的事情,我不认为 Android 项目视图 是 JetBrains 想要支持的东西,也许在某个时候会有 Kotlin Multiplatform Project View,但目前不会。

(如果您打开 Spring、NodeJS、iOS 或任何其他类型的项目,Android 项目视图同样会损坏)