返回

Expo编译错误:Kotlin 2.0 Compose Compiler 解决方案

Android

编译 Expo App 时遇到 "Starting in Kotlin 2.0..." Compose 编译器错误,咋回事?

搞 Expo App 开发,Android 项目,Kotlin 版本 1.9.0,编译时蹦出个错误:

Starting in Kotlin 2.0, the Compose Compiler Gradle plugin is required when compose is enabled. See the following link for more information: https://d.android.com/r/studio-ui/compose-compiler

看着就头大。说的是 Kotlin 2.0 开始,如果启用了 Compose,就必须用 Compose Compiler Gradle 插件。可我这项目明明用的 Kotlin 1.9.0 啊,咋也报这个错?我还在 composeOptions 里设置了 kotlinCompilerExtensionVersion 为 "1.5.14" 呢。

下面把遇到问题的根源,和咋解决,都给你掰扯清楚。

一、问题出在哪儿?

这问题的核心在于,项目构建配置的 Kotlin 版本 和 实际使用的 Compose Compiler 版本不匹配 , 加上了 Gradle 插件版本的依赖冲突导致了这个提示的误报。

虽然项目整体设置的 Kotlin 版本是 1.9.0,但项目的依赖关系或者 Gradle 插件间接的将 Compose 相关的部分自动的提升到了Kotlin 2.0 以上的版本。 即使你在build.gradle 里明确写了ext.kotlin_version = '1.9.0',并不能保证所有相关的库都严格遵守这个版本。有些第三方库,或者 Android Gradle 插件,可能会在内部依赖更高版本的 Kotlin 和 Compose Compiler。

让我们仔细看一下报错时的 build.gradle 部分配置:

allprojects {
buildscript {
    ext.kotlin_version = '1.9.0'
    // ... 其他配置 ...
    dependencies {
        // ... 其他依赖 ...
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20" // 关键点!
        // ... 其他依赖 ...
    }
}
}

android {
    // ... 其他配置 ...

    composeOptions {
        kotlinCompilerExtensionVersion "1.5.14"
    }
}

看到问题了吗?在 buildscriptdependencies 块里,kotlin-gradle-plugin 的版本被明确设置为了 2.0.20。这就是问题所在!这里明确地将项目构建过程中用于编译 Kotlin 代码的 Gradle 插件版本设定为 2.0.20。这就会触发错误消息中的条件: "Starting in Kotlin 2.0..."。

二、咋解决?

解决这个问题的思路很清晰:就是要确保构建过程中用到的 Kotlin 和 Compose Compiler 版本是兼容的,而且别超过 Kotlin 2.0 的界限(如果暂时不想升级到 2.0 的话)。下面提供几种解决办法:

1. 统一 Kotlin 和 Compose Compiler 版本 (推荐)

最稳妥的办法是把 Kotlin Gradle Plugin 和 Compose Compiler 的版本都统一起来, 保持他们的兼容性.

  • 原理: 这样做可以保证整个构建过程使用的都是匹配的版本,避免了各种兼容性问题。

  • 操作步骤:

    1. 查看版本对应关系表: 访问 Compose to Kotlin Compatibility Map 查看 Kotlin 和 Compose Compiler 推荐的对应版本。

    2. 修改 build.gradle (project-level): 修改 build.gradle 文件, 把 Kotlin 版本和 Compose Compiler 版本设定到兼容的版本号. 比如,如果要用 Kotlin 1.9.0,Compose Compiler 的版本可以选择 1.5.1 (请根据上面的链接确认最新的兼容版本):

      buildscript {
          ext.kotlin_version = '1.9.0' // kotlin 版本
           // ...
          dependencies {
                // ...
                classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // 和上面版本一致
                // ...
          }
      
      }
      // ...
      
      // app 级 build.gradle
      android {
            //...
             composeOptions {
                kotlinCompilerExtensionVersion "1.5.1" // Compose compiler 版本
            }
          //...
      }
      
      
    3. Clean & Rebuild : 清理项目(Build -> Clean Project),然后重新构建项目(Build -> Rebuild Project)。

  • 进阶技巧 : 可以定义一个变量专门用来保存 Compose Compiler version.

    buildscript {
        ext.kotlin_version = '1.9.0'
        ext.compose_compiler_version = '1.5.1' // 新增一个变量
          // ...
    }
    

    然后在 composeOptions 里面用:

     android {
          // ...
         composeOptions {
                kotlinCompilerExtensionVersion "$compose_compiler_version"
         }
            // ...
    }
    

2. 降级 Kotlin Gradle Plugin 版本 (不推荐, 除非有特殊需要)

如果你有特别的理由不想升级项目的 Kotlin 版本,那可以尝试降低 kotlin-gradle-plugin 的版本。

  • 原理: 将 Kotlin Gradle Plugin 降级到一个低于 2.0.0 的版本, 这样就不会触发那个关于 Kotlin 2.0 的错误信息了。

  • 操作步骤:

    1. 修改 build.gradle (project-level):

      buildscript {
           // ...
          dependencies {
              // ...
              classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0" // 改回 1.9.0 或者其他低于 2.0.0 的版本
              // ...
          }
      }
      
    2. 同步并重新构建: 修改后,同步 Gradle(File -> Sync Project with Gradle Files)并重新构建项目。

  • 注意 : 这个方法并不推荐。降级 Gradle 插件版本可能会引入其他问题,比如不兼容最新的 Android Gradle Plugin 等. 只在确定必须这么做的情况下使用.

3. 检查依赖关系 (有时有用)

有时候,错误可能是由项目中的某些库间接依赖了高版本的 Kotlin 或 Compose Compiler 导致的。这时候, 可以用 Gradle 的依赖分析工具看看。

  • 原理: Gradle 提供了依赖树分析工具, 可以帮你看到项目所有的直接和间接依赖, 以及它们之间的关系.

  • 操作步骤:

    1. 运行依赖分析命令: 在 Android Studio 的 Terminal 里运行 ./gradlew :app:dependencies (把 app 换成你的 module 名字, 如果只有一个 module 的话可以直接 ./gradlew dependencies).

    2. 分析输出: 这个命令会输出一个很长的文本, 里面列出了所有依赖. 可以搜索 kotlin-stdlib 或者 compose-compiler 这些关键词, 看一下它们最终被解析成了什么版本.

    3. 强制指定版本 (如果需要): 如果发现某个库间接依赖了高版本,可以尝试在你的 build.gradle (app-level) 里面强制指定版本:

      dependencies {
          // ... 其他依赖 ...
           implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0") { //强制使用指定版本的 Kotlin
              force = true
          }
      }
      

      不过这种方法也可能造成新的问题, 要小心使用.

4.检查 Expo 的配置文件(针对 Expo 项目)

  • 原理 : 如果你在用 Expo, 有可能某些配置是 Expo 帮你自动管理的。 这种情况下, 直接修改 Gradle 文件可能不会生效, 或者被覆盖掉.
  • 操作步骤 :
    1. 仔细看 Expo 文档。通常,Expo 对这类构建的细节, 都应该会有很明确的指引的。
    2. 检查 app.json 或者 eas.json 这类文件. 看一下是否有地方配置了 Kotlin 或 Compose Compiler 相关参数, 或者有没有提到需要手动处理这些.
    3. 尝试使用 Expo 提供的配置方式. Expo 经常有它自己的一套逻辑. 按照它的方式来, 一般更能避免奇奇怪怪的问题.

三、安全建议 (可选, 根据实际情况)

如果你的项目涉及敏感数据或有较高的安全性要求,那么以下建议值得考虑:

  • 保持库最新: 及时更新 Kotlin、Compose Compiler 以及其他依赖库到最新稳定版本。新版本通常会修复安全漏洞。
  • 使用混淆: 在发布应用时开启代码混淆 (ProGuard 或 R8),增加反编译难度。
  • 定期审查 : 定期分析项目依赖. 及时发现过时的或者有安全漏洞的组件。

按照上面的分析和处理办法,基本能搞定这个 Compose 编译器的报错。选哪个方法,主要还是看项目的实际情况。推荐第一个,比较彻底和稳妥。

Good luck!