跳转到内容
Skip
3.2k

Kotlin 2 迁移

Kotlin 2 引入了许多改进,包括将 Compose 编译器集成到 Kotlin 编译器本身1。Skip 0.9.2 采用 Kotlin 2 作为目标语言,这涉及对 Skip 创建的 Gradle 项目进行一些更改2。在内部,这涉及更改 Skip 添加到 Android Gradle 项目中的部分依赖项。

这些更改在大多数情况下对 Skip 框架项目是透明的。但在 Skip 0.9.2 之前创建的 Skip 应用项目需要进行一些更改,才能与新的 Compose 编译器配合使用。

要升级 Skip 应用项目,请在任意文本编辑器(如 Xcode、Android Studio 或 TextEdit)中打开 Android/app/build.gradle.kts 文件,并进行以下更改:

  1. plugins { } 块中添加 alias(libs.plugins.kotlin.compose)
  2. composeOptions { } 块中移除 kotlinCompilerExtensionVersion = libs.versions.kotlin.compose.compiler.extension.get()

skip-build-plugin 包含在所有通过 skip init 创建的 Skip 应用项目中,如果检测到你的项目需要更新,它会提供有用的错误信息:

需要升级的 Skip 项目在 Xcode 中的错误信息{: style=“width: 100%;”} {: style=“text-align: center; margin: auto;“}

Android/app/build.gradle.kts 的必要更改

Section titled “Android/app/build.gradle.kts 的必要更改”

下面是对 Android/app/build.gradle.kts 所需更改的简要对比。完整示例可以参考 skip-hello 应用的构建文件:https://source.skip.dev/skipapp-hello/blob/main/Android/app/build.gradle.kts

修改前:

plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.android.application)
id("skip-build-plugin")
}
android {
namespace = group as String
compileSdk = libs.versions.android.sdk.compile.get().toInt()
compileOptions {
sourceCompatibility = JavaVersion.toVersion(libs.versions.jvm.get())
targetCompatibility = JavaVersion.toVersion(libs.versions.jvm.get())
}
defaultConfig {
minSdk = libs.versions.android.sdk.min.get().toInt()
targetSdk = libs.versions.android.sdk.compile.get().toInt()
}
composeOptions {
kotlinCompilerExtensionVersion = libs.versions.kotlin.compose.compiler.extension.get()
}
}

修改后:

plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose) // 添加此行
alias(libs.plugins.android.application)
id("skip-build-plugin")
}
android {
namespace = group as String
compileSdk = libs.versions.android.sdk.compile.get().toInt()
compileOptions {
sourceCompatibility = JavaVersion.toVersion(libs.versions.jvm.get())
targetCompatibility = JavaVersion.toVersion(libs.versions.jvm.get())
}
kotlinOptions {
jvmTarget = libs.versions.jvm.get().toString() // 添加此行
}
defaultConfig {
minSdk = libs.versions.android.sdk.min.get().toInt()
targetSdk = libs.versions.android.sdk.compile.get().toInt()
}
composeOptions {
// kotlinCompilerExtensionVersion = libs.versions.kotlin.compose.compiler.extension.get() // 删除此行
}
}

Error: Inconsistent JVM-target compatibility detected for tasks ‘compileDebugJavaWithJavac’ (17) and ‘compileDebugKotlin’ (22).

Section titled “Error: Inconsistent JVM-target compatibility detected for tasks ‘compileDebugJavaWithJavac’ (17) and ‘compileDebugKotlin’ (22).”

整个 Gradle 项目必须使用相同的 JVM 目标,包括你自己的应用以及所有 Skip 依赖项。之前通过 compileOptions 块的 sourceCompatibilitytargetCompatibility 属性自动完成,但现在还需要使用 jvmTarget 属性将其添加到 kotlinOptions 块中。按如下方式编辑你的 build.gradle.kts 文件:

android {
compileOptions {
sourceCompatibility = JavaVersion.toVersion(libs.versions.jvm.get())
targetCompatibility = JavaVersion.toVersion(libs.versions.jvm.get())
}
kotlinOptions {
jvmTarget = libs.versions.jvm.get().toString() // 添加此行
}
}

当 Compose 编译器插件未添加到应用的 Android/app/build.gradle.kts 文件中时,会出现此错误。请确保你已按照本迁移指南中的说明修复此错误。

此错误的简要表示如下:

e: org.jetbrains.kotlin.backend.common.BackendException: Backend Internal error: Exception during IR lowering
> Task :app:compileDebugKotlin FAILED
File being compiled: /opt/src/github/skiptools/skipapp-hello/Android/app/src/main/kotlin/hello/skip/Main.kt
The root cause java.lang.RuntimeException was thrown at: org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate(FunctionCodegen.kt:50)
at org.jetbrains.kotlin.backend.common.CodegenUtil.reportBackendException(CodegenUtil.kt:253)
at org.jetbrains.kotlin.backend.common.CodegenUtil.reportBackendException$default(CodegenUtil.kt:236)
at org.jetbrains.kotlin.backend.common.phaser.PerformByIrFilePhase.invokeSequential(performByIrFile.kt:65)
Caused by: java.lang.RuntimeException: Exception while generating code for:
FUN LOCAL_FUNCTION_FOR_LAMBDA name:PresentationRootView$lambda$1 visibility:private modality:FINAL <> (ctx:skip.ui.ComposeContext) returnType:kotlin.Unit?
VALUE_PARAMETER name:ctx index:0 type:skip.ui.ComposeContext
BLOCK_BODY
VAR name:contentContext type:skip.ui.ComposeContext [val]
  1. Jetpack Compose 编译器迁移到 Kotlin 仓库:https://android-developers.googleblog.com/2024/04/jetpack-compose-compiler-moving-to-kotlin-repository.html

  2. 迁移 Jetpack Compose 项目:https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compiler.html#migrating-a-jetpack-compose-project