Android中的Desugaring

Desugaring是Android的一种机制,使得新的Java库可以在较低的API级别上运行。当新的Java特性如TimeAPI在高版本Android中引入时,D8/R8工具会在构建过程中将这些新特性转换为低版本API能理解的代码,确保应用的向后兼容性。通过启用coreLibraryDesugaring和调整Gradle配置,开发者可以让旧版本Android设备使用最新的Java库。

前言

自从 Kotlin 成为 Android 开发的推荐语言以来,大多数开发人员已经从 Java 转向 Kotlin。Kotlin 无疑超出了所有人的预期,现在是许多人最喜欢的语言。就我自己和 Android 开发人员的观点而言,如果有人要求我切换回 Java,我会想一百万次才放弃 Kotlin-first API 提供的所有好处。

但是,Oracle 的人们一直在努力改进 Java。例如,Java 10 的var声明变量的特性和 Java 8 的time API & stream API。Time API 实际上比经典的 DateTime API 有很多改进,例如Duration、Period等等。我会把这部分留给你去探索,现在让我们谈谈什么是desugaring以及它与所有这些东西有什么关系。

什么是Desugaring?

开发任何新的 Android 操作系统时,都会附带一堆 Java 类,这些类为需要这些类才能运行的应用程序提供支持。让我们考虑一下这种情况下的 Time API。它被添加到 Android API 级别 26,因此,使用此库的应用程序将在较低的 API 级别上崩溃,例如 Marshmallow (API 23)。
这是desugaring出现的时候。它允许较低的 API 级别使用新的 Java 库。我们将看到它是如何做到的,但在此之前,让我们启动 Android Studio 进行快速演示,以使事情更清楚。

实际的

保持简短,我将使用新的 Time API 打印出当前月份,然后在 Android R (API 30) 和 Android M (API 23) 上对其进行测试。

tv_month.text = LocalDate.now().month.name



正如预期的那样,它在 API 30 上工作,但在 API 23 上失败并出现NoClassDefFoundError异常。要解决此问题,我们需要使用以下步骤在我们的项目中启用desugaring功能。

  • 将 Android gradle 插件设置为4.0或更高版本。
  • 在编译选项中,启用coreLibraryDesugaringEnabled标志并将 Java目标和源兼容性设置为 Java 8。
  • 启用multidex(适用于支持 API 级别 20 或以下的项目)
  • 添加desugaring依赖
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
​

在引擎盖下

那么这里到底发生了什么?操作系统中缺失的 Java 类是如何突然出现的?由于D8/R8工具,这一切皆有可能。在深入了解他们如何做到这一点之前,让我们先了解一下历史,以了解这些工具到底是什么。

探索 D8/R8

Android 开发人员已经使用ProGuard很长时间了,并且在代码压缩和混淆方面已被证明是一个“首选”工具。让我们看看使用 ProGuard 时代码是如何流动的。

源代码由 JVM 转换为字节码。该字节码经过 ProGuard 优化,最后由 dex 编译器转换为 dex 可执行文件。
由于代码在捆绑到 APK 之前必须经过几个阶段,因此构建时间会增加。为了减少这个时间,谷歌在 2015 年左右推出了Jack & Jill 编译器,它做了同样的事情,但在一个阶段。


由于技术和工具的不断进步,该解决方案无法满足新出现的需求。因此,谷歌在 2017 年左右放弃了它,他们回到了经典的编译方式。但这一次,他们重写了 dex 编译器,并引入了一个名为D8的工具。

这被证明是非常成功的,甚至能够支持 Kotlin 的发展。Google 进一步引入了R8代码收缩器,它基本上是 ProGuard 和 D8 的组合。这有助于减少编译过程中的一个阶段。

回到desugaring,D8/R8 阶段是提供缺失 Java 类的真正魔术师。在将我们应用程序的源代码转换为 dex 代码的同时,它还为新的 java 库添加了 dex 代码,然后最终捆绑在 APK 中。该过程如下图所示。

这就是旧的 android API 级别可以使用新的 Java 库的方式!

结论

简单来说,Desugaring是一种为新的 Java 库提供向后兼容性的工具。当我们想到它时,这是一个非常简单的概念,但要从内到外理解它,我们需要了解一些围绕它的东西。我希望你能从这个文章中得到一些有用的东西。

<think>我们注意到用户的问题是关于在AndroidStudio中配置和增加Java语言支持。根据提供的引用内容,我们可以整理出以下信息:引用[1]提到在Android11中,Google改进了对Java和C++的支持,包括升级了Java库支持(来自OpenJDK9、10和11的新API),并在AndroidStudio4.0中推出了Java库“脱糖”(desugaring),使得在较低版本的Android设备上也能使用较新的JavaAPI。引用[2]展示了如何将Java代码转换为Kotlin代码,但用户的需求是增加Java支持,因此这个引用可能不直接相关。引用[3]是一篇关于AndroidStudio下载安装配置的详细教程,可能包含设置Java环境的信息。引用[4]详细介绍了在Ubuntu下配置Java和Android环境变量的步骤,包括如何安装搜狗输入法(因为系统默认输入法可能导致编译问题),以及如何设置JDK的软链接等。用户的问题是在AndroidStudio中添加Java语言支持。实际上,AndroidStudio默认就支持Java开发。但是,用户可能指的是配置项目使用特定版本的Java,或者确保项目能够使用较新的Java语言特性。因此,我们可以从以下几个方面回答:1.**确认Java开发环境**:AndroidStudio本身内置了JDK(通常为OpenJDK),但也可以使用自己安装的JDK。2.**配置项目的Java版本**:在项目的build.gradle文件中可以设置Java版本。3.**使用较新JavaAPI(脱糖)**:通过启用脱糖功能,可以在低版本Android上使用高版本JavaAPI。具体步骤:###1.确认AndroidStudio使用的JDK-打开AndroidStudio,点击菜单栏的File>ProjectStructure(或者File>Settings>Appearance&Behavior>SystemSettings>AndroidSDK)。-在SDKLocation中,可以看到JDKLocation,这里可以设置AndroidStudio使用的JDK路径。默认情况下,AndroidStudio会使用自带的JDK(通常位于AndroidStudio安装目录下的jre目录)。你也可以选择自己安装的JDK。###2.在项目中配置Java版本-打开项目中的`build.gradle`(Module级别),在`android`块中设置`compileOptions`,例如:```groovyandroid{compileOptions{sourceCompatibilityJavaVersion.VERSION_11targetCompatibilityJavaVersion.VERSION_11}}```这里设置使用Java11。注意:根据项目需求选择合适的版本(如1.8、11等)。###3.启用脱糖(Desugaring)以使用较新的JavaAPI-在同一个`build.gradle`文件中,确保在`compileOptions`中启用核心库脱糖,并添加依赖:```groovyandroid{compileOptions{coreLibraryDesugaringEnabledtruesourceCompatibilityJavaVersion.VERSION_11targetCompatibilityJavaVersion.VERSION_11}}dependencies{coreLibraryDesugaring'com.android.tools:desugar_jdk_libs:1.1.5'}```这样就可以在项目中使用Java11的API,并且这些API会在低版本Android设备上运行(通过脱糖处理)。###4.配置环境变量(可选)-如果需要在终端使用Java命令(例如使用gradlew命令),可能需要配置系统环境变量。引用[4]中提供了在Ubuntu下配置环境变量的方法,但如果是Windows或macOS,配置方式不同。通常,在AndroidStudio中开发并不需要单独配置系统环境变量,因为AndroidStudio会使用其自带的JDK或你指定的JDK。###5.创建新项目时选择Java-在创建新项目时,AndroidStudio会提供选择语言的选项,选择Java即可。注意:从AndroidStudioArcticFox(2020.3.1)版本开始,新建项目默认使用Kotlin,所以需要手动选择Java。**总结步骤**:1.确保AndroidStudio已安装并配置了合适的JDK。2.在项目的build.gradle文件中设置所需的Java版本。3.如果需要使用高版本JavaAPI且兼容低版本Android,启用脱糖并添加依赖。4.创建新项目时,在向导中选择Java作为编程语言。相关问题:1.如何在AndroidStudio中更改项目的JDK版本?2.脱糖(Desugaring)是什么?它是如何工作的?3.在Android开发中,Java和Kotlin的主要区别是什么?4.如何解决AndroidStudio中与Java环境相关的编译错误?</think>### 在 Android Studio 中配置 Java 语言支持 Android Studio 默认支持 Java 开发,无需额外安装语言包。以下是配置步骤: --- #### 1. **验证 JDK 环境** - Android Studio 内置 OpenJDK,但可自定义 JDK: ```groovy // 在项目的 build.gradle 中指定 JDK 版本 android { compileOptions { sourceCompatibility JavaVersion.VERSION_11 // 设置 Java 11 targetCompatibility JavaVersion.VERSION_11 } } ``` - **手动配置 JDK**(可选): 通过 `File > Project Structure > SDK Location`,选择本地安装的 JDK 路径(需已配置环境变量)[^4]。 --- #### 2. **启用 Java 新特性支持(脱糖)** 为在低版本 Android 设备使用新 Java API(如 `java.time`): ```groovy // 在模块的 build.gradle 中添加 android { compileOptions { coreLibraryDesugaringEnabled true // 启用脱糖 } } dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' } ``` 此功能通过 **脱糖(Desugaring)** 将高版本 API 转换为低版本兼容形式[^1]。 --- #### 3. **创建 Java 项目** - 新建项目时,在向导中选择 **Java** 作为语言: `File > New > New Project > Language: Java` - 现有 Kotlin 项目添加 Java 文件: 右键点击包名 > `New > Java Class` --- #### 4. **解决常见问题** - **编译错误**:确保 `build.gradle` 中 Java 版本与 JDK 一致。 - **环境变量配置**(Linux/Ubuntu): 在 `~/.bashrc` 添加: ```bash export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 export PATH=$PATH:$JAVA_HOME/bin ``` 执行 `source ~/.bashrc` 生效[^4]。 - **输入法冲突**:某些系统输入法可能导致编译失败,可切换为 Fcitx 输入法[^4]。 --- #### 5. **检查配置结果** - 创建测试类: ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } ``` - 成功编译运行即表示 Java 支持已生效[^2]。 > **关键提示**:Android Studio 4.0+ 通过脱糖支持 OpenJDK 11 API,无需依赖设备系统版本[^1]。 --- ### 相关问题 1. **如何在低版本 Android 设备上使用 Java 11 的新特性?** (涉及脱糖机制的具体实现与兼容性处理) 2. **Android Studio 中同时使用 Java 和 Kotlin 的混合开发如何配置?** (需解决两种语言的互操作与 Gradle 设置) 3. **如何为不同的 Android 模块指定独立的 Java 版本?** (涉及模块化项目中的 JDK 版本管理) 4. **脱糖技术对应用性能有何影响?如何优化?** (需分析脱糖后的字节码效率与解决方案)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值