“为什么选择Apache Harmony”或“如何在Android上使用Java 8”

2022-08-31 15:27:37

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

问题:

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

答案 1

他们为什么使用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的原生代码端有着密切的关系......这可能会使移植出现问题。


答案 2

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

有一些库向后移植 Java 8 API 的部分(有关在最新的 Android 版本中对这些 API 的本机支持,请参阅下面的更新部分):

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

您可以使用 retrolambda(以及 gradle-retrolambda 插件)在 Android 开发中利用 lambdas。


更新

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) 添加了 API 支持。java.time


更新 2020/01/17

Android Studio 4.0 支持使用许多 Java 8 语言 API,通过使用称为“去糖”的技术,而无需为您的 app 提供最低 API 级别:
https://developer.android.com/studio/preview/features#j8-desugar

此版本支持以下 API 集:

  • 顺序流 (java.util.stream)
  • 的子集java.time
  • java.util.function
  • 最近添加到java.util.{Map,Collection,Comparator}
  • 可选 (和 ) 以及一些对上述 API 有用的其他新类java.util.Optionaljava.util.OptionalIntjava.util.OptionalDouble
  • 对 (上的新方法) 的一些补充,以及java.util.concurrent.atomicAtomicIntegerAtomicLongAtomicReference)
  • ConcurrentHashMap(修复了安卓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的文章中找到:


推荐