了解 Android API 级别

Xamarin.Android 具有多个 Android API 级别设置,用于确定应用的与多个版本的 Android 的兼容性。 本指南介绍这些设置的含义、如何配置这些设置,以及它们在运行时对应用的影响。

快速入门

Xamarin.Android 公开三个 Android API 级别项目设置:

  • 目标框架 – 指定要用于生成应用程序的框架。 Xamarin.Android 在编译时使用此 API 级别。

  • 最低 Android 版本 – 指定希望应用支持的最旧 Android 版本。 Android 在 运行时 使用此 API 级别。

  • 目标 Android 版本 – 指定应用要运行的 Android 版本。 Android 在 运行时 使用此 API 级别。

必须先安装该 API 级别的 SDK 平台组件,然后才能为项目配置 API 级别。 有关下载和安装 Android SDK 组件的详细信息,请参阅 Android SDK 安装程序

注意

从 2021 年 8 月开始,Google Play Console 要求新应用面向 API 级别 30 (Android 11.0) 或更高版本。 从 2021 年 11 月开始,现有应用需要面向 API 级别 30 或更高版本。 有关详细信息,请参阅 Play Console 文档“创建和设置应用”中的 Play Console 的目标 API 级别要求

通常,所有三个 Xamarin.Android API 级别都设置为相同的值。 在“应用程序”页上,将“使用 Android 版本(目标框架)编译”设置为最新的稳定 API 版本(或者至少设置为具有所需的所有功能的 Android 版本)。 在以下屏幕截图中,目标框架设置为 Android 7.1(API 级别 25 - Nougat)

Target Framework version defaults to Compile using Android version

在“Android 清单”页上,将最低 Android 版本设置为使用 SDK 版本进行编译,并将目标 Android 版本设置为与目标框架版本相同的值(在以下屏幕截图中,目标 Android 框架设置为 Android 7.1 (Nougat)):

Minimum and Target Android versions set to Target Framework version

如果要保持与早期版本的 Android 的向后兼容性,请将“最低 Android 目标版本”设置为你希望应用支持的最早版本的 Android。 (请注意,API 级别 14 是 Google Play 服务和 Firebase 支持所需的最低 API 级别。)以下示例配置支持从 API 级别 14 到 API 级别 25 的 Android 版本:

Compile using API level 25 Nougat, Minimum Android version set to API level 14

如果你的应用支持多个 Android 版本,你的代码必须包含运行时检查,以确保你的应用适用于最低 Android 版本设置(有关详细信息,请参阅下面的 Android 版本的运行时检查)。 如果要使用或创建库,请参阅下面的 API 级别和库,了解为库配置 API 级别设置的最佳做法。

Android 版本和 API 级别

随着 Android 平台的发展和新的 Android 版本发布,每个 Android 版本都分配了一个唯一的整数标识符,称为 API 级别。 因此,每个 Android 版本对应于单个 Android API 级别。 由于用户在较旧版本和最新版本的 Android 上安装应用,因此实际 Android 应用必须设计为使用多个 Android API 级别。

Android 版本

Android 的每个版本都采用多个名称:

  • Android 版本,例如 Android 9.0
  • 代码(或甜点)名称,如 Pie
  • 相应的 API 级别,例如 API 级别 28

Android 代码名称可能与多个版本和 API 级别相对应(如下表所示),但每个 Android 版本都对应于一个 API 级别。

此外,Xamarin.Android 还定义了映射到当前已知 Android API 级别的生成版本代码。 下表可以帮助你在 API 级别、Android 版本、代码名称和 Xamarin.Android 生成版本代码之间进行转换(生成版本代码是在 Android.OS 命名空间中定义的):

名称 版本 API 级别 已发布 生成版本代码
Q 10.0 29 2020 年 8 月 BuildVersionCodes.Q
饼图 9.0 28 2018 年 8 月 BuildVersionCodes.P
Oreo 8.1 27 2017 年 12 月 BuildVersionCodes.OMr1
Oreo 8.0 26 2017 年 8 月 BuildVersionCodes.O
Nougat 7.1 25 2016 年 12 月 BuildVersionCodes.NMr1
Nougat 7.0 24 2016 年 8 月 BuildVersionCodes.N
Marshmallow 6.0 23 2015 年 8 月 BuildVersionCodes.M
Lollipop 5.1 22 2015 年 3 月 BuildVersionCodes.LollipopMr1
Lollipop 5.0 21 Nov 2014 BuildVersionCodes.Lollipop
Kitkat Watch 4.4W 20 Jun 2014 BuildVersionCodes.KitKatWatch
Kitkat 4.4 19 2013 年 10 月 BuildVersionCodes.KitKat
Jelly Bean 4.3 18 Jul 2013 BuildVersionCodes.JellyBeanMr2
Jelly Bean 4.2-4.2.2 17 2012 年 11 月 BuildVersionCodes.JellyBeanMr1
Jelly Bean 4.1-4.1.1 16 2012 年 6 月 BuildVersionCodes.JellyBean
Ice Cream Sandwich 4.0.3-4.0.4 15 2011 年 12 月 BuildVersionCodes.IceCreamSandwichMr1
Ice Cream Sandwich 4.0-4.0.2 14 2011 年 10 月 BuildVersionCodes.IceCreamSandwich
蜂巢 3.2 13 2011 年 6 月 BuildVersionCodes.HoneyCombMr2
蜂巢 3.1.x 12 2011 年 5 月 BuildVersionCodes.HoneyCombMr1
蜂巢 3.0.x 11 2011 年 2 月 BuildVersionCodes.HoneyComb
Gingerbread 2.3.3-2.3.4 10 2011 年 2 月 BuildVersionCodes.GingerBreadMr1
Gingerbread 2.3-2.3.2 9 2010 年 11 月 BuildVersionCodes.GingerBread
Froyo 2.2.x 8 2010 年 6 月 BuildVersionCodes.Froyo
Eclair 2.1.x 7 2010 年 1 月 BuildVersionCodes.EclairMr1
Eclair 2.0.1 6 2009 年 12 月 BuildVersionCodes.Eclair01
Eclair 2.0 5 2009 年 11 月 BuildVersionCodes.Eclair
圆环图 1.6 4 2009 年 9 月 BuildVersionCodes.Donut
Cupcake 1.5 3 2009 年 5 月 BuildVersionCodes.Cupcake
Base 1.1 2 2009 年 2 月 BuildVersionCodes.Base11
Base 1.0 1 2008 年 10 月 BuildVersionCodes.Base

如下表所示,新的 Android 版本经常发布 - 有时每年发布多个版本。 因此,可能运行应用的 Android 设备的整个体系包括各种较旧和较新的 Android 版本。 如何保证应用在这么多不同版本的 Android 上运行一致且可靠? Android 的 API 级别可帮助你管理此问题。

Android API 级别

每个 Android 设备在完全一个 API 级别运行,此 API 级别保证每个 Android 平台版本是唯一的。 API 级别精确标识应用可以调用的 API 集的版本;它标识作为开发人员编码的清单元素、权限等的组合。 Android 的 API 级别系统可帮助 Android 在设备上安装应用程序之前确定应用程序是否与 Android 系统映像兼容。

生成应用程序时,它包含以下 API 级别信息:

  • 目标要运行应用的 Android API 级别。

  • Android 设备必须运行应用的最低 Android API 级别。

这些设置用于确保安装时在 Android 设备上正确运行应用所需的功能可用。 如果没有,则阻止应用在该设备上运行。 例如,如果 Android 设备的 API 级别低于为应用指定的最低 API 级别,则 Android 设备将阻止用户安装应用。

项目 API 级别设置

以下部分介绍如何使用 SDK 管理器为要面向的 API 级别准备开发环境,然后详细说明如何配置 Target Framework最低 Android 版本,以及 Xamarin.Android 中的目标 Android 版本设置。

Android SDK 平台

在 Xamarin.Android 中选择目标或最低 API 级别之前,必须安装对应于该 API 级别的 Android SDK 平台版本。 目标框架、最低 Android 版本和目标 Android 版本的可用选项范围仅限于已安装的 Android SDK 版本范围。 可以使用 SDK 管理器来验证是否已安装所需的 Android SDK 版本,并可用于添加应用所需的任何新 API 级别。 如果不熟悉如何安装 API 级别,请参阅 Android SDK 安装

目标 Framework

目标框架(也称为 compileSdkVersion)是应用在生成时编译的特定 Android 框架版本(API 级别)。 此设置指定应用预期在运行时使用的 API,但不会影响安装应用时实际可用的 API。 因此,更改目标框架设置不会更改运行时行为。

目标框架标识了应用程序所链接的库版本,这一设置决定了应用程序中可以使用哪些 API。 例如,如果要使用 Android 5.0 Lollipop 中引入的 NotificationBuilder.SetCategory 方法,则必须将目标框架设置为 API 级别 21 (Lollipop) 或更高版本。 如果将项目的目标框架设置为 API 级别(如 API 级别 19 (KitKat)) 并尝试调用代码中的 SetCategory 方法,则会出现编译错误。

建议始终使用最新的可用目标框架版本进行编译。 这样做可为您提供有用的警告信息,提醒您代码可能调用的任何已弃用 API。 当您使用最新发布的支持库时,使用最新的目标框架版本尤为重要 – 每个库都希望您的应用程序以该支持库的最低 API 级别或更高级别编译。

若要在 Visual Studio 中访问目标框架设置,请在“解决方案资源管理器”中打开项目属性,然后选择“应用程序”页:

Application page of project Properties

通过在“使用 Android 版本编译”的下拉菜单中选择 API 级别来设置目标框架,如下所示。

最低 Android 版本

最低 Android 版本(也称为 minSdkVersion)是可以安装和运行应用程序的 Android OS(即最低 API 级别)的最旧版本。 默认情况下,应用只能在与目标框架设置或更高版本匹配的设备上安装;如果最低 Android 版本设置低于目标框架设置,则应用也可以在早期版本的 Android 上运行。 例如,如果将目标框架设置为 Android 7.1 (Nougat) 并将最低 Android 版本设置为 Android 4.0.3 (Ice Cream Sandwich),则应用可以安装在 API 级别 15 到 API 级别 25 的任何平台上(包括 API 级别 25)。

尽管你的应用可能会成功生成并安装在此系列平台上,但不能保证它成功在所有平台上运行。 例如,如果你的应用安装在 Android 5.0 (Lollipop) 上,并且你的代码调用的 API 仅在 Android 7.1 (Nougat) 及更新版本中可用,则你的应用将收到运行时错误,并可能崩溃。 因此,您的代码必须确保在运行时,只调用 Android 设备支持的 API。 换句话说,代码必须包括显式运行时检查,以确保应用仅在最近足够支持它们的设备上使用较新的 API。 Android 版本的运行时检查,本指南后面部分介绍了如何将这些运行时检查添加到代码。

若要访问 Visual Studio 中的最低 Android 版本设置,请在“解决方案资源管理器”中打开项目属性,然后选择“Android 清单”页。 在“最低 Android 版本”的下拉菜单中,可以为应用程序选择最低 Android 版本:

Minimum Android to target option set to Compile using SDK version

如果选择“使用 SDK 版本进行编译”,则最低 Android 版本将与目标框架设置相同。

目标 Android 版本

目标 Android 版本(也称为 targetSdkVersion)是应用需要在其中运行的 Android 设备的 API 级别。 Android 使用此设置来确定是否启用任何兼容性行为,这可确保应用继续按照预期的方式工作。 Android 使用应用的目标 Android 版本设置来确定哪些行为更改可以应用于应用而不中断它(这是 Android 提供向前兼容性的方式)。

目标框架和目标 Android 版本虽然名称非常相似,但并不相同。 目标框架设置将目标 API 级别信息传达给 Xamarin.Android,以便在编译时使用,而目标 Android 版本将目标 API 级别信息传达给 Android,以便在运行时(在设备上安装和运行应用时)使用。

若要在 Visual Studio 中访问此设置,请在“解决方案资源管理器”中打开项目属性,然后选择“Android 清单”页。 在“目标 Android 版本”下的下拉菜单中,可以为应用程序选择目标 Android 版本:

Target Android version set to Compile using SDK version

建议将目标 Android 版本显式设置为用于测试应用的最新版本的 Android。 理想情况下,它应设置为最新的 Android SDK 版本,这样就可以在处理行为更改之前使用新的 API。 对于大多数开发人员,不建议将目标 Android 版本设置为“使用 SDK 版本进行编译”

通常,目标 Android 版本应受最低 Android 版本和目标框架的约束。 即:

最低 Android 版本 <= 目标 Android 版本 <= 目标框架

有关 SDK 级别的详细信息,请参阅 Android 开发人员 uses-sdk 文档。

运行时检查 Android 版本

随着 Android 的每个新版本发布,框架 API 将更新以提供新的或替换功能。 除了极少数例外,早期 Android 版本中的 API 功能会转发到较新的 Android 版本中,无需修改。 因此,如果应用在特定 Android API 级别上运行,它通常能够在以后的 Android API 级别上运行,而无需修改。 但是,如果还需要在早期版本的 Android 上运行应用,该怎么办?

如果选择的最低 Android 版本低于目标框架设置,则某些 API 在运行时可能不适用于应用。 但是,你的应用仍然可以在早期设备上运行,但功能会降低。 对于与最低 Android 版本设置相对应的 Android 平台上不可用的每个 API,代码必须显式检查 Android.OS.Build.VERSION.SdkInt 属性的值,以确定应用正在运行的平台的 API 级别。 如果 API 级别比支持要调用的 API 的最低 Android 版本,则代码必须找到一种方法来正常运行,而无需进行此 API 调用。

例如,假设我们希望使用 NotificationBuilder.SetCategory 方法在 Android 5.0 Lollipop(及更高版本)上运行时对通知进行分类,但我们仍希望应用在早期版本的 Android 上运行,例如 Android 4.1 Jelly Bean(其中 SetCategory 不可用)。 参考本指南开头的 Android 版本表,我们看到 Android 5.0 Lollipop 的生成版本代码为 Android.OS.BuildVersionCodes.Lollipop。 为了支持旧版 Android(其中 SetCategory 不可用),我们的代码可以在运行时检测 API 级别,并且仅在 API 级别大于或等于 Lollipop 生成版本代码时有条件地调用 SetCategory

if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
{
    builder.SetCategory(Notification.CategoryEmail);
}

在此示例中,应用的目标框架设置为 Android 5.0(API 级别 21),其最低 Android 版本设置为 Android 4.1(API 级别 16)。 由于 SetCategory 在 API 级别 Android.OS.BuildVersionCodes.Lollipop 及更高版本中可用,因此仅当实际可用时,此示例代码才会调用 SetCategory,在 API 级别为 16、17、18、19 或 20 时尝试调用 SetCategory。 仅当通知未正确排序(因为它们未按类型分类),这些早期 Android 版本中的功能才会减少,但仍会发布通知以提醒用户。 我们的应用仍然有效,但其功能略有减弱。

通常,生成版本检查可帮助代码在运行时决定执行新方式与旧方式。 例如:

if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
{
    // Do things the Lollipop way
}
else
{
    // Do things the pre-Lollipop way
}

在缺少一个或多个 API 的旧版 Android 版本上运行时,没有快速简单的规则来解释如何减少或修改应用的功能。 在某些情况下(如上面的 SetCategory 示例中),在 API 调用不可用时省略 API 调用就足够了。 不过,在其他情况下,当检测到 Android.OS.Build.VERSION.SdkInt 小于应用程序所需的 API 级别时,您可能需要实施替代功能,以提供最佳体验。

API 级别和库

创建 Xamarin.Android 库项目(如类库或绑定库)时,只能配置目标框架设置 – 最低 Android 版本,而目标 Android 版本设置不可用。 这是因为没有“Android 清单”页:

Only the Compile using Android version option is available

最低 Android 版本和目标 Android 版本设置不可用,因为生成的库不是可在任何 Android 版本上运行的独立应用,具体取决于它打包的应用。 可以指定要如何编译库,但无法预测库将运行的平台 API 级别。 考虑到这一点,在使用或创建库时应遵守以下最佳做法:

  • 使用 Android 库时 – 如果在应用程序中使用 Android 库,请确保将应用程序的目标框架设置设置为至少与库的目标框架设置一样高的 API 级别。

  • 创建 Android 库时 – 如果要创建供其他应用程序使用的 Android 库,请确保将其目标框架设置设置为编译所需的最低 API 级别。

建议使用这些最佳做法来帮助防止库尝试调用在运行时不可用的 API(这可能导致应用崩溃)的情况。 如果你是库开发人员,则应努力将 API 调用的使用限制在 API 总面积中一小部分既定的子集内。 这样做有助于确保库可以在更广泛的 Android 版本中安全地使用。

总结

本指南介绍了如何使用 Android API 级别跨不同版本的 Android 管理应用兼容性。 它提供了配置 Xamarin.Android 目标框架最低 Android 版本以及目标 Android 版本项目设置的详细步骤。 它提供了有关使用 Android SDK 管理器安装 SDK 包的说明,包括有关如何在运行时编写代码以处理不同 API 级别的示例,并介绍了如何在创建或使用 Android 库时管理 API 级别。 它还提供了一个综合列表,用于将 API 级别与 Android 版本号(如 Android 4.4)、Android 版本名称(如 Kitkat)和 Xamarin.Android 生成版本代码相关联。