【问题标题】:Which Android versions run which Java versions?哪些 Android 版本运行哪些 Java 版本?
【发布时间】:2019-01-10 13:31:35
【问题描述】:

我刚刚尝试在 Android 4.0 设备上运行使用 Java 8 编译的应用程序。虽然我习惯于仔细查看 Android 文档中的 Android API 级别,以确保我只使用 Android 4.0 上可用的 API,但我不太习惯确保我没有使用Java 本身的任何功能在 Android 4.0 上不可用。

考虑以下代码,它尝试从 View 类导入 initializeScrollbars() API,因为无论出于何种原因,它一直是来自官方 SDK 的 removed

try {
    final Method initializeScrollbars = android.view.View.class.getDeclaredMethod("initializeScrollbars", TypedArray.class);
    initializeScrollbars.invoke(this, a);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {        
    e.printStackTrace();
}

虽然此代码在我的 Android 8.0 测试系统上运行良好,但在 Android 4.0 上却无法运行。错误是:

Could not find method java.lang.ReflectiveOperationException.printStackTrace

经过一番研究,我发现ReflectiveOperationException 在 Java 7 之前不可用,因此显然 Android 4.0 不支持 Java 7。

这让我想知道:是否有一个概述清楚地显示了哪些 Android 版本附带了哪些 Java 版本?例如如何找到第一个支持 Java 7 的 Android 版本?我怎样才能找到第一个支持 Java 8 的 Android 版本?

这确实很容易找到,但我只是没看到它。谷歌搜索总是会导致人们询问 Android Studio 支持的 Java 版本,而不是 Android 本身。

那么,任何人都可以对此有所了解吗?我知道它一定是在某个非常明显的地方,但我似乎没有找到它......

【问题讨论】:

    标签: java android


    【解决方案1】:

    因此,显然,Android 4.0 不支持 Java 7。

    根据您的定义,Android 不支持任何版本的 Java。 Android SDK 中的javajavax 类与Java 的任何版本都不完全匹配,无论是数字版本(例如,6、7、8)还是您认为Java SE/EE/ME 的任何版本。

    是否有概述清楚地显示哪些 Android 版本附带哪些 Java 版本

    就语言特性(例如 lambda 表达式)而言,引用 the documentation

    Android Studio 3.0 及更高版本支持所有 Java 7 语言功能和 Java 8 语言功能的子集,这些功能因平台版本而异

    在这里,“Android Studio”实际上是指编译您的源代码并创建 Dalvik 字节码的构建工具。当前的工具可以支持所有版本的 Android 上的所有 Java 7 和一些 Java 8 功能。其他 Java 8 功能仅在 API 级别 24+ 上可用,通常是因为它们依赖于当时仅添加到 Android SDK 的某些类。

    但您似乎关心的是类和方法,在这种情况下,没有任何 Java 版本到任何 Android 版本的简单映射。

    此外,您正在使用反射侵入框架类,这意味着您的结果不仅会因 Android 版本而异,而且会因设备型号而异,因为设备制造商可以并且确实会更改框架类的实现.

    【讨论】:

    • 那么我怎样才能确保 Java 代码也适用于旧的 Android 版本呢?对于纯 Android API,这很容易,只需检查 API 级别,但是像 ReflectiveOperationException 这样在 Android 8 上存在但在 Android 4.0 上没有的内置 Java 内容呢?诚然,我的示例做了一些通常不应该做的事情,但是在其他情况下,您是否会使用一些 Java 方法/类,这些方法/类在 Android 8 上但在 Android 4 上却没有,而且您不知道吗?这有点令人不安。
    • @Andreas:“那么我怎样才能确保 Java 代码也适用于旧的 Android 版本呢?” -- 适当地设置你的minSdkVersion,并让构建工具指导你,因为当你直接使用比minSdkVersion 更新的东西时,你会收到来自 Lint 的抱怨。另外,拥有完整的测试套件。
    • 好吧,但是 minSdkVersion 在我的 build.gradle 中设置为 14,而且我没有收到任何来自 Lint 的关于 ReflectiveOperationException 的警告...
    • @Andreas:当然。您没有直接引用 ReflectiveOperationException,因此 Lint 没有什么可抱怨的。看起来您的特定设备中存在一些您正在绊倒的错误,因为有人没想到您会做您正在做的事情。当您尝试使用反射访问 Android SDK 之外的内容时,就会发生这种情况。
    • @EliTheHuman:Dalvik 运行时环境已被 ART 取代。这个答案指的是字节码格式上下文中的 Dalvik,仍在使用。
    【解决方案2】:

    来自https://source.android.com/setup/build/older-versions#jdk 上的“支持旧版本”AOSP 文档:

    支持的版本

    Android 7.0(牛轧糖)-Android 8.0(奥利奥):

    Ubuntu:OpenJDK 8

    Mac OS X:JDK 8u45 或更高版本

    Android 5.x (Lollipop) – Android 6.0 (Marshmallow):

    Ubuntu:OpenJDK 7

    Mac OS X:jdk-7u71-macosx-x64.dmg

    Android 2.3.x (Gingerbread) – Android 4.4.x (KitKat):

    Ubuntu:Java JDK 6

    Mac OS X:Java JDK 6

    Android 1.5 (Cupcake) – Android 2.2.x (Froyo):

    Ubuntu:Java JDK 5

    文档目前(2022 年 2 月)没有在 Android >=9.0 和 JDK(我可以找到)之间建立任何关联;我怀疑这一点被忽略了,因为在 Ubuntu 20.04 LTS 发布之前的某个时候,安装文档似乎没有得到彻底更新。 确实提到最新的 master 分支 (Android 12.0.0_r32) 带有一个 prebuilts 文件夹,其中包含必要的 JDK。

    【讨论】:

      猜你喜欢
      • 2012-05-25
      • 2018-06-21
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-02
      • 2018-09-22
      相关资源
      最近更新 更多