ネットワーク選択

このページでは、Androidが同時に利用可能なネットワークを選択する方法について説明します。このネットワーク選択メカニズムは、Androidがアプリとシステムのネットワーク要求をどのように実行するかに影響し、アプリのデフォルトネットワークがどのように選択されるかに影響します。

ネットワーク選択動作

このセクションでは、Android12以降を実行しているデバイスとAndroid11以下を実行しているデバイスのネットワーク選択動作について説明します。

Android 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-FiSTAでネットワークを起動できるようにする将来のネットワークに役立ちます。ネットワークエージェントがこのフラグを宣言しない場合、エージェントがネットワークのパフォーマンスを評価する機会を得る前に、見込みのあるネットワークは要求を処理しなかったために破棄されます。

2つのネットワークが特定の要求を処理でき、ポリシーの観点から同等である場合、選択は現在要求を処理しているネットワークを優先します。要求を処理しているネットワークがない場合は、2つのうちのいずれかを選択します。その後、ポリシーフラグが変更されるまで、このネットワークが引き続き優先されます。

ネットワーク選択機能の実装は、AOSPの接続モジュールにあります。ネットワーク選択のポリシーロジックは、 NetworkRankerクラスとそのヘルパークラスにあります。つまり、デバイスメーカーは、ネットワーク選択コードを直接カスタマイズすることはできませんが、代わりにNetworkScoreのフラグを使用して、ネットワークに関する必要な情報を伝達する必要があります。

Android 11

Android 11以下を実行しているデバイスの場合、Androidは、ネットワークエージェント( NetworkAgent )の実装から送信された単純な整数に基づいてネットワーク選択を実行します。 Androidは、リクエストごとに、リクエストを満たすことができる数値スコアが最も高いネットワークを選択します。この数値スコアは、ネットワークエージェントによって送信された整数に加えて、ネットワークが検証されているかどうか、ネットワークがVPNであるかどうかなど、いくつかの条件に基づいて与えられる追加のボーナスまたはペナルティで構成されます。個々のネットワークエージェントは、ポリシーを決定するために相互に同期します。

2つのネットワークが特定の要求を処理でき、同じ数値スコアを持つ場合、動作は定義されていません。

NetworkScoreクラス

ネットワーク選択機能の中心的なクラスはNetworkScoreです。このクラスには、使用可能なフラグとsetKeepConnectedReasonメソッドのAPIとドキュメントが含まれています。

NetworkScoreクラスは、そのビルダークラスを介して構築され、初期化時にNetworkAgentコンストラクターに渡される必要があります。ネットワークスコアは、 NetworkAgent#sendNetworkScoreメソッドを使用していつでも更新できます。

ネットワークエージェントの実装例

AOSPには、さまざまなネットワークエージェントの実装例が含まれています。実装例は次のとおりです。

  • DcNetworkAgent :ネットワークスコアを使用してモバイルネットワークのポリシーを伝達します
  • ClientModeImpl.WifiNetworkAgent :ネットワークスコアを使用してWi-Fiネットワークのポリシーを伝達します。この実装には、 POLICY_EXITINGフラグを使用したネットワークスコアのレガシー整数との下位互換性が含まれています。

Android12にアップグレードするデバイス

デバイスをAndroid12にアップグレードするデバイスメーカーは、 NetworkScoreクラスを使用するようにネットワークエージェントの実装を変更する必要があります。 Android 11以下で使用されるレガシー整数はNetworkScoreで渡されますが、Android 12ではロギングと非回帰の目的でのみ使用されます。Android12では、デバイスメーカーはNetworkScoreフラグを使用して必要な変更を表現する必要があります。次に、Connectivity Mainlineモジュールは、フラグを使用してネットワーク選択を決定します。 Android 11以下のコードを使用しているが、Android 12の実装に反してビルドしているデバイスメーカーは、レガシー整数を更新するメソッドがAndroid 12で削除されているため、ビルドエラーが発生する可能性があります。

内部NetworkFactoryクラスを使用するネットワークエージェントの場合、ファクトリが作成できるネットワークの最強のスコアを表すNetworkScoreオブジェクトでスコアフィルタを表現する必要があります。これは、Android 12では、 NetworkFactoryクラスが、Android 11以下のすべてのリクエストではなく、 NetworkFactoryに宣言されたスコアフィルターに一致するリクエストのみを渡すためです。

すべてのリクエストがNetworkFactoryに渡されるわけではないように、実装とバッテリー節約を容易にするためにフィルターを渡すことをお勧めします。ただし、カスタム実装ですべてのリクエストをNetworkFactoryに渡す必要がある場合は、通常のNetworkFactory.registerメソッドの代わりにNetworkFactory.registerIgnoringScoreを登録できます。この方法を使用する場合は、工場が満たすことができない要求を評価しないことでバッテリーを節約するために、工場が作成できる最高のスコアを最も正確に表すスコアフィルターを渡すことをお勧めします。

検証

Androidデバイスでのネットワーク選択の動作を確認するには、次のテストを使用します。

実装が正しくないと、デバイスのデフォルトネットワーク( ConnectivityManager.registerDefaultNetworkCallbackでネットワークコールバックを使用するときにシステムがアプリに送信するネットワーク)の選択など、 NetworkCallbackの使用に応じて予期しないネットワークがアプリに返される可能性があります。

誤った実装で発生する可能性のあるもう1つの問題は、ネットワークエージェントが要求の対象とならないスコアで表示され、直後に破棄されることによって引き起こされる深刻なバッテリーの消耗です。エージェントの起動と分解を繰り返すと、バッテリーを大量に消費する可能性があります。