首页 > 解决方案 > 多平台项目中的 Android 上下文

问题描述

我想知道是否可以使用 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 源中,但同步失败。

提前致谢

标签: androidkotlinkotlin-multiplatform

解决方案


是的你可以。

在您的build.gradle文件中,您的目标不是 android(presets.android),而是jvmpresets.jvm)并将其称为 android。

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

如果你想以 android 为目标,你还必须使用 android gradle 插件。为了能够使用 androidMain 文件夹中的 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)
        }
    }
}

推荐阅读