由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不同)

截屏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等字段

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容