当前位置: 首页>后端>正文

由sourceCompatibility产生的思考

当项目的gradle升级到8.0之后,由于项目中使用了room,因此也使用了ksp替代kapt,然后我在编译的过程中就遇到了如下错误

Caused by: org.gradle.api.GradleException: 'compileDebugJavaWithJavac' task (current target is 1.8) and 'kspDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.

google一番,找到了几个比较相关的解释

  1. https://stackoverflow.com/questions/69079963/how-to-set-compilejava-task-11-and-compilekotlin-task-1-8-jvm-target-com
  2. https://stackoverflow.com/questions/52492459/how-does-sourcecompatibility-and-targetcompatibility-impact-number-of-supported

解决方案也很简单,把项目中的这几个版本都指定为一致就行

compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
kotlinOptions {
        jvmTarget = "17"
}

那么问题又来了,java版本设置得如此高,为什么能够在设备上正常运行,没有崩溃?

android在编译kotlin和java的代码过程中,经历过如下几个步骤

源码 → 字节码 → 字节码脱糖 → dex

编译器后端会根据我们指定的minSdkVersion来决定目标字节码版本(不同版本的安卓系统支持的jdk不同)

由sourceCompatibility产生的思考,第1张
截屏2023-09-27 17.40.25.png

根据官方文档对jdk版本的说明,当编译sdk版本指定为34之后,我们就可以使用部分jdk 17的api

再次澄清几个jdk使用的不同的地方的概念

AGP插件运行在Gradle中,Gradle的jdk版本则是AGP插件运行的版本,通常来说,Gradle的jdk版本可以比AGP插件要求的jdk版本高,

sourceCompatibility指定了在源代码中可以使用的java sdk api的版本,如果没有指定sourceCompatibility,那么在源代码中可以使用的jdk版本由指定的java 工具链版本或者运行Gradle的jdk版本,sourceCompatibility低于targetCompatibility,targetCompatibility和jvmTarget指定了字节码的版本

因此总结来说,你当然可以使用高版本的Java的api,前提是你的工具链支持这些特点
为了保持本地编译环境和远程ci编译环境的结果的一致性,最好指定sourceCompatibility等字段


https://www.xamrdz.com/backend/3rk1940965.html

相关文章: