网络选择

本页介绍 Android 如何在同时可用的网络之间进行选择。这种网络选择机制会影响 Android 如何满足应用和系统网络请求,并影响如何选择应用的默认网络。

网络选择行为

本节介绍运行 Android 12 或更高版本的设备以及运行 Android 11 及更低版本的设备的网络选择行为。

安卓 12

对于运行 Android 12 或更高版本的设备,Android 使用NetworkScore类在可用网络之间进行选择。此类包含制定策略决策所需的许多标志。每个标志在语义上代表对网络选择很重要的网络属性。

网络代理 ( NetworkAgent ) 使用POLICY_TRANSPORT_PRIMARY标志来指定当存在相同传输的多个网络时首选网络。一个典型的例子是双 SIM 卡设备,在设置中有一个开关,让用户选择默认使用的 SIM 卡。在给定的传输中,Android 更喜欢带有POLICY_TRANSPORT_PRIMARY标志的网络,而不是没有该标志的网络。

网络代理使用POLICY_EXITING标志来标识预计将很快断开连接的网络。一个典型的例子是当用户走出网络范围时 Wi-Fi 网络质量下降。如果另一个没有此标志的网络可用,Android 会避免使用带有此标志的网络。每个单独的网络代理都可以确定网络何时降级到足以被视为退出。

NetworkScore类还允许网络代理使用KEEP_CONNECTED_FOR_HANDOVER标志和NetworkScore.Builder.setKeepConnectedReason方法声明网络保持正常。此KEEP_CONNECTED_FOR_HANDOVER标志对于允许网络代理在辅助 Wi-Fi STA 上启动网络而不使其成为主要网络的预期网络非常有用,直到评估网络的性能。如果网络代理没有声明此标志,则在代理有机会评估网络性能之前,预期网络会因为不服务任何请求而被拆除。

如果两个网络可以为给定请求提供服务并且从策略的角度来看是等效的,则选择更喜欢当前正在为请求提供服务的网络。如果没有网络正在为请求提供服务,它会选择两者之一,之后该网络将继续被首选,直到策略标志发生变化。

网络选择功能的实现在 AOSP 的连接模块中。网络选择的策略逻辑可以在NetworkRanker类及其助手类中找到。这意味着设备制造商不能直接自定义网络选择代码,而是必须使用NetworkScore中的标志来传达有关网络的所需信息。

安卓 11

对于运行 Android 11 或更低版本的设备,Android 根据网络代理 ( NetworkAgent ) 的实现发送的简单整数执行网络选择。对于每个请求,Android 会选择能够满足请求的最高数字分数的网络。该数字分数由网络代理发送的整数加上基于多种条件(例如网络是否经过验证或网络是否为 VPN)给出的额外奖励或惩罚组成。各个网络代理相互同步以做出策略决策。

如果两个网络可以为给定的请求提供服务并且具有相同的数字分数,则行为是未定义的。

NetworkScore 类

网络选择功能的中心类是NetworkScore 。此类包含可用标志的 API 和文档以及setKeepConnectedReason方法。

NetworkScore类必须通过其构建器类构建,并在初始化时传递给NetworkAgent构造函数。可以使用NetworkAgent#sendNetworkScore方法随时更新网络分数。

网络代理实现示例

AOSP 包括各种网络代理的示例实现。以下是示例实现:

  • DcNetworkAgent :使用网络分数来传达移动网络的策略
  • ClientModeImpl.WifiNetworkAgent :使用网络分数来传达 Wi-Fi 网络的策略。此实现包括向后兼容使用POLICY_EXITING标志的网络分数的旧整数。

升级到 Android 12 的设备

将设备升级到 Android 12 的设备制造商必须修改其网络代理实现以使用NetworkScore类。 Android 11 或更低版本中使用的旧整数在NetworkScore中传递,但在 Android 12 中仅用于日志记录和非回归目的。在 Android 12 中,设备制造商必须使用NetworkScore标志来表达所需的更改。然后,Connectivity Mainline 模块使用这些标志来做出网络选择决策。使用适用于 Android 11 或更低版本的代码但针对 Android 12 中的实现进行构建的设备制造商可能会出现构建错误,因为更新旧整数的方法已在 Android 12 中移除。

对于使用内部NetworkFactory类的网络代理,它们必须在NetworkScore对象中表达其分数过滤器,该对象表示工厂可以创建的网络的最强分数。这是因为在 Android 12 中, NetworkFactory类仅传递与声明给NetworkFactory的分数过滤器匹配的请求,而不是在 Android 11 及更低版本中传递所有请求。

我们建议传递一个过滤器以便于实现和节省电池,以便并非所有请求都传递给NetworkFactory 。但是,如果您的自定义实现需要将所有请求传递给NetworkFactory ,您可以注册NetworkFactory.registerIgnoringScore而不是常规的NetworkFactory.register方法。如果使用此方法,我们建议传递一个分数过滤器,该过滤器最准确地代表工厂可以创建的最佳分数,以便通过不评估工厂无法满足的请求来节省电池。

验证

要验证 Android 设备上的网络选择行为,请使用以下测试:

不正确的实现可能会导致意外的网络返回给应用程序以响应它们对NetworkCallback的使用,包括选择设备的默认网络(当应用程序使用ConnectivityManager.registerDefaultNetworkCallback的网络回调时系统发送给应用程序的网络)。

不正确实施的另一个可能问题是严重的电池消耗,这是由于网络代理的得分不符合任何请求并在之后立即被拆除。如果代理反复启动和拆除,这可能会消耗大量电池。