太长不看版
当你的 Android gradle plugin
版别低于 4.2时(后面简称为AGP)。Android Studio
(后简称AS) 默许运用 java7
作为语法检查。
当你的代码,或许你依靠的代码中存在 java8 种的语法,比方 lambda
。 而且你没有增加 java8 兼容装备。AS在语法分析,或许编译的时候,都会报错。
lambda expressions are not supported in -source 7
为了处理这个报错,能够经过三种方法处理。
- 代码中消除 java8 的lambda。(很难做到)
- 增加 java8 的兼容装备 (简单做到)
- 升级 AGP 到 4.2 (中等难度)
所以,为了处理这个过错,挑选方法 2
是较为简单的。
遇到了问题
项目是一个混合 Flutter 的项目,运用到了 flutter shared_preferences。 在4.15日打包失利,过错提示为:
.../flutter/.pub-cache/hosted/pub.flutter-io.cn/shared_preferences_android-2.1.1/android/src/main/java/io/flutter/plugins/sharedpreferences/Messages.java:84: error: static interface methods are not supported in -source 7
static[@nonnull](https://github.com/nonnull)MessageCodec getCodec() {
^
(use -source 8 or higher to enable static interface methods)
.../flutter/.pub-cache/hosted/pub.flutter-io.cn/shared_preferences_android-2.1.1/android/src/main/java/io/flutter/plugins/sharedpreferences/Messages.java:103: error: lambda expressions are not supported in -source 7
(message, reply) -> {
^
(use -source 8 or higher to enable lambda expressions)
2 errors
检查 shared_preferences 依靠为 ^2.10.0。 最近一周没有改正这个依靠,而且最近打包都是正常的。
在搜索引擎中搜索
-source 8 or higher to enable lambda expressions
提示应该在项目中增加
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
可是主项目现已增加过这个代码块了,难道要改 shared_preferences?
查找处理方案
查找 flutter shared_preferences
github 。发现有这个 issue
。
[(github.com/flutter/flu…)]
有人回复能够经过如下方法处理
dependency_overrides:
shared_preferences_android: 2.1.0
shared_preferences_ios: 2.1.0
能够看出是写死了 flutter
依靠的版别号。
在 flutter
中 ^2.10.0
代表取 2.10.x 的最高版别。去掉 ,就是写死版别号。
持续看这个 issue
,后面有人发了另外一个处理方法
对应的 pr
[github.com/flutter/pac…]
对应的代码片段如下:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
确实是在 shared_preferences
的 build.gradle
中增加的,也处理了问题,不再报错。
考虑: 为什么能够这样处理
问问 chatgpt
下面这段代码是什么意思?
问: Android 中下面这段代码是什么意思
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
答:
这段代码是在 Android build.gradle 文件中的装备选项,它指定了 Java 代码编译时所运用的源码和方针代码兼容性版别都为 Java 8。
- `sourceCompatibility JavaVersion.VERSION_1_8` 表明源码兼容性版别为 Java 8。
- `targetCompatibility JavaVersion.VERSION_1_8` 表明方针代码兼容性版别为 Java 8。
这意味着你能够在你的代码中运用 Java 8 的新言语特性和 API,而且编译后的 APK 能够在支撑 Java 8 的设备上运转。
反问自己:理解了吗?
自问自答:没有。
测验:假如在我的项目里去掉 sourceCompatibility JavaVersion.VERSION_1_8
会怎样样?
IDE
直接摆烂
猜想: Android Studio
默许运用 Java 7
用于代码检查,以及编译吗?
验证猜想
前置准备
1: 需求用的指令
javap -v file
经过这个指令,能够得到 .class
文件对应的java编译版别
2: Android项目中编译出来的 .class
文件在哪里?
Android项目中,java文件的编译产品目录为:
app/build/intermediates/javac/debug/compileDebugJavaWithJavac
假如你发现这个目录下是空的,试试下面几个方法
- 确定你的现已
rebuild
成功 - 删除
build
目录,而且rebuild
项目 - 假如你没有
java
代码,都是kotlin
代码,那么这个目录肯定是空的。写一个java
类吧。
验证场景一: 删除 java_1.8 兼容性代码, 运转指令 javap -v MainActivity.java
得到以下信息
上图中的 major version: 51 表明这个文件是由 java7 编译的。
验证场景二: 保留 java_1.8 兼容性代码, 运转指令 javap -v MainActivity.java
得到以下信息
上图中 major version: 52 表明这个文件是由 java 8 编译的。
开始定论:Android Studio 默许用 java7
编译代码。
假如需求 java8
的语法,比方 lambda
,需求额定加上
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
上面的定论是有误的,下面持续说为什么过错。
再考虑:是谁决议了这个编译版别的?
考虑一:项目怎样用 java7 来编译了?
Android Studio
中,JDK
的版别号现已是 java8
或许是 java11
。
我绝对不会指定 java7
来编译项意图。
考虑二:sp的开发者有那么不专业吗?
shared_preferences_android 项目,提交 2.1.11版别的那位开发同学。
详细提交 commit
[github.com/flutter/pac…]
他写这些代码的时候,IDE直接也报错了吧,还能提交吗?不可能这么不专业吧。
因而我猜想有其他工具,来确定项目运用什么版别的 java
来编译。
猜想一: 是 gradle
决议项意图java编译版别吗?
验证猜想:直接问 chatgpt
问:android gradle 会运用什么java版别来编译android项目?
答:
根据官方文档,Android Gradle插件默许运用Java 8版别来编译Android项目。然而,从Android Gradle插件3.0版别开始,还支撑运用Java 7或更高版别来编译Android项目。
开发者能够在build.gradle文件中的android {}代码块中经过设置compileOptions {}来指定运用的Java版别。例如,设置为Java 7:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
注意,要在项目中运用Java 8的新特性(例如Lambda表达式),需求在运用模块的build.gradle文件中增加以下代码来启用Java 8言语功能:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// For Java 8 language support
jackOptions {
enabled true
}
}
可是从Android Gradle插件3.0版别开始,官方现已弃用Jack编译器,主张运用Java 8言语功能时,运用D8或R8编译器。
从chatgpt
得到的答案为 Android Gradle Plugin
,简称 AGP
,决议了Android
项意图java
编译版别。
那么 AGP
版别和 Java
编译版别的联系是什么呢?
阅读了 AGP
发布的日志
developer.android.google.cn/build/relea…
发现 AGP
从 4.2 版别开始,默许运用 java8
来编译代码,而且 AS 以 java8
作为检查基准,就是图片中的 language level
。
能够得到定论: 当你的 AGP
版别高于或等于 4.2 ,你不需求增加
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
也能够运用 java8
语法糖,编译器会默许运用 java8
来编译你的代码。
小结:项意图编译版别默许是 AGP
版别决议的。或许你能够增加兼容性代码来决议编译版别。
回答上面的猜忌二:
shared_preferences_android 项目,提交 2.1.11版别的那位开发同学。 详细提交
commit
他写这些代码的时候,IDE直接也报错了吧,还能提交吗?不可能这么不专业吧。
查看 shared_preferences_android 2.11.1
的 agp
版别
github.com/flutter/pac…
AGP 7.2.2
默许运用 java8
来编译项目。
所以提交 shared_preferences_android lambda
代码的开发者,项目不会报错。
因而能够得到如下小结:项目中 AGP
版别为 4.1.2
,默许运用 java7
编译项目,
第三方依靠的 AGP
即便设置到高版别,也会运用 主项意图低版别 AGP
。
假如第三方依靠要运用 java8 lambda
,必须增加兼容装备。
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}