Android 多平台项目中的上下文

Android context in multiplatform project

我想知道是否可以使用 kotlin-multiplatform 插件访问 androidMain sourceSets 中的 Android 上下文应用程序。

这是 build.gradle 文件

apply plugin: 'kotlin-multiplatform'

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos")   \
                                ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'iOS') {
            compilations.main.outputKinds('FRAMEWORK')
        }

        fromPreset(presets.jvm, 'android')
    }

    sourceSets {

        commonMain {
            kotlin.srcDir('src')
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
                // coroutine
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.1.0"
            }
        }

        androidMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                // Timber
                implementation "com.jakewharton.timber:timber:$timber_version"
                // coroutine
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.0"
            }
        }
    }
}

我尝试将 'com.android.application' 插件添加到 androidMain 源中,但同步失败。

提前致谢

是的,你可以。

在您的 build.gradle 文件中,您没有定位 android 本身 (presets.android),而是 jvm (presets.jvm) 并称其为 android。

就像现在一样,您的构建将生成一个 JAR 文件而不是 aar 文件。

如果你想以 android 为目标,你还必须使用 android gradle 插件。为了能够使用 android 主文件夹中的 android 框架,请更新您的 build.gradle 文件。下面是一个例子:

apply plugin: 'org.jetbrains.kotlin.multiplatform'
apply plugin: 'com.android.library'

android {
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName '1.0'
    }
    buildTypes {
        release {
            minifyEnabled false
        }
    }

        // By default the android gradle plugin expects to find the kotlin source files in 
        // the folder `main` and the test in the folder `test`. This is to be able place 
        // the source code files inside androidMain and androidTest folders
    sourceSets {
        main {
            manifest.srcFile 'src/androidMain/AndroidManifest.xml'
            java.srcDirs = ['src/androidMain/kotlin']
            res.srcDirs = ['src/androidMain/res']
        }
        test {
            java.srcDirs = ['src/androidTest/kotlin']
            res.srcDirs = ['src/androidTest/res']
        }
    }
}

dependencies {
    implementation "com.jakewharton.timber:timber:$timber_version
}

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos")   \
                                ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'iOS') {
            compilations.main.outputKinds('FRAMEWORK')
        }

        fromPreset(presets.android, 'android')
    }
    sourceSets {
        commonMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
                // coroutine
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.1.0"
            }
        }
        androidMain {
            dependencies {
                api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
            }
        }
    }
}

task buildiOSFramework(type: Sync) {

    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'

    inputs.property "mode", mode
    dependsOn kotlin.targets.iOS.compilations.main.linkTaskName("FRAMEWORK", mode)

    from { kotlin.targets.iOS.compilations.main.getBinary("FRAMEWORK", mode).parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew $@\n"
            setExecutable(true)
        }
    }
}