64

到目前为止,我们大多数人都听说过 Java 8 将带来的很酷的特性,但 Android 不支持它。这是因为 Google 使用了适用于 Android 的Apache Harmony。这就是阻止我们(Android 应用程序开发人员)使用 lambda、接口中的默认实现、打开 String 等等来改进我们的代码的原因。当然,我们会处理一段时间,但是如果我们在应用程序中使用的某些库开始使用 Java 8 特性怎么办?据我所知,这是行不通的(如有错误请纠正我)。这会在Standard -Java 和Android -Java 之间造成不兼容。这不可能是谷歌的意图,或者至少我想不出为什么一家开发广泛采用的操作系统的公司不想永久留在一个旧的Java 版本。

问题:

  • 他们为什么使用 Apache Harmony?
  • 为什么他们不能采用更新版本的java?
  • 如果他们不想要 Oracle 的 Java,为什么他们不能使用OpenJDK的一个子集(这里是许可菜鸟)?
  • 您知道更新使用的 Java 版本的任何计划吗?
  • 您知道在当前 Android 系统上使用 Java 8 类的任何方法吗?
4

3 回答 3

55

他们为什么使用 Apache Harmony?

因为 Sun 拒绝按照可接受的条款向 Google 提供 Sun(现为 Oracle)Java 的许可。谷歌和 Sun 进行了谈判,但他们最终放弃了这笔交易。

Nitpick:事实上,Android 库不是 Apache Harmony。他们一开始是基于 Harmony,但两个代码库已经出现分歧。此外,Apache Harmony 项目于 2011 年 11 月正式“退役”。

为什么他们不能采用更新版本的java?

首先,Android 不运行 Java(tm)。它在具有不同指令集的虚拟机上运行与 Java 相同的语言,其类库在功能上等同于 Java 类库的子集(+ Android 特定库)。

从技术角度来看,他们可以……但前提是他们投入大量工作来为 Android 平台实现 Java 7 和 Java 8 语言特性、库特性等。

更新- 从 Android 19 (KitKat) 和 Eclipse ADT 22.6 开始,Android 现在支持 Java 7 语言扩展;见http://tools.android.com/recent/eclipseadt226preview

如果他们不想要 Oracle 的 Java,为什么他们不能使用 OpenJDK 的子集?

我认为切换到 OpenJDK 不会改变任何事情。Oracle Java 和 OpenJDK 99.9% 相同。

无论如何,可能存在许可和相关的法律问题。(要了解这一点,请阅读甲骨文与谷歌的诉讼......这将是上诉。)

更有可能的是,谷歌没有看到足够的商业价值来抵消它所需要的(巨大的)改变努力,以及它对 Android 生态系统造成的破坏……它已经遭受了碎片化问题的困扰。

您知道更新使用的 Java 版本的任何计划吗?

不,我没有。这并不意味着没有计划,但如果有,则不公开。

您知道在当前 Android 系统上使用 Java 8 类的任何方法吗?

你可以移植它们。或者至少,您可以尝试移植它们。(一些 Java API 与 JVM 的本机代码端有着密切的关系……这可能会给移植带来问题。)

于 2013-06-04T15:24:44.213 回答
12

您知道在当前 Android 系统上使用 Java 8 类的任何方法吗?

有一些库支持 Java 8 API 的部分内容(请参阅下面的更新部分,了解最新 Android 版本对这些 API 的原生支持):

  • ThreeTenABP为 Android 优化的 Java 8 日期和时间 API 向后移植
  • 流支持是 Java 8 java.util.function(功能接口)和java.util.stream(流)API 的向后移植,适用于 Java 6 或 7 的用户,并补充了 Java 6java.util.concurrent中不存在的选定添加项。

您可以使用retrolambda(连同gradle-retrolambda插件)在 Android 开发中使用 lambda。


更新

Android Studio 3.0开始为一些 Java 8 语言特性提供内置支持,它们是:

  • Lambda 表达式
  • 方法参考
  • 类型注释(信息在编译时可用,但在运行时不可用)
  • 重复注释
  • 默认和静态接口方法

同样从 API 级别 24 开始,以下 Java 8 API 可用:

  • java.util.stream
  • java.util.function
  • java.lang.FunctionalInterface
  • java.lang.annotation.Repeatable
  • java.lang.reflect.AnnotatedElement.getAnnotationsByType(Class)
  • java.lang.reflect.Method.isDefault()

API 级别 26 (Android O) 添加了java.timeAPI 支持。


更新 2020/01/17

Android Studio 4.0包括对使用许多 Java 8 语言 API 的支持,通过使用称为去糖的技术,无需为您的应用设置最低 API 级别:
https ://developer.android.com/studio/preview/features#j8-desugar

此版本支持以下 API 集:

  • 顺序流 ( java.util.stream)
  • 的一个子集java.time
  • java.util.function
  • 最近添加到java.util.{Map,Collection,Comparator}
  • 可选项 ( java.util.Optional,java.util.OptionalIntjava.util.OptionalDouble) 和其他一些对上述 API 有用的新类
  • 对(和的java.util.concurrent.atomic新方法)的一些补充AtomicIntegerAtomicLongAtomicReference
  • ConcurrentHashMap(修复了 Android 5.0 的错误)

为了支持这些语言 API,D8 编译了一个单独的库 DEX 文件,其中包含缺少的 API 的实现并将其包含在您的应用程序中。脱糖过程会重写您的应用程序代码,以在运行时使用此库。

要启用对这些语言 API 的支持,请在模块build.gradle文件中包含以下内容:

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4'
}

有关如何实现脱糖的更多技术细节,可以在 Jake Wharton 的文章中找到:

于 2014-10-04T22:59:51.437 回答
5

更新。

Android 计划使用 OpenJDK。可能是因为他们像您一样思考并且想要使用 Java 8 功能。看到这个

于 2015-12-30T11:42:34.543 回答