網絡選擇

本頁介紹 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的網絡回調時系統發送給應用程序的網絡)。

不正確實施的另一個可能問題是嚴重的電池消耗,這是由於網絡代理的得分不符合任何請求並在之後立即被拆除。如果代理反复啟動和拆除,這可能會消耗大量電池。