ネットワークに関する問題のトラブルシューティング

アプリによって生成されたネットワーク トラフィックは、デバイスのバッテリー駆動時間に大きく影響する可能性があります。トラフィックを最適化するには トラフィックを測定してソースを特定する必要がありますネットワーク リクエストは、ユーザー アクション、独自のアプリコード、アプリと通信しているサーバーから直接送信される可能性があります。

このトピックでは、ネットワーク トラフィックをモニタリングして分類する方法と、問題の特定と解決に関するガイダンスについて説明します。

Network Profiler を使用してリクエストをモニタリングする

Network Profiler を使用して、アプリケーションのネットワーク リクエストを追跡します。アプリがデータを転送した方法とタイミングをモニタリングし、基盤となるコードを適切に最適化できます。



図 1. ネットワーク トラフィックの追跡ネットワーク トラフィック パターンは、リクエストのプリフェッチやアップロードのバンドルによって効率が大幅に向上することを示しています。

データ転送の頻度と各接続で転送されるデータの量をモニタリングすることで、アプリでバッテリー効率を改善できる領域を特定できます。一般的に、遅延可能な短いスパイクを探します。

転送の急増の原因をより適切に特定するために、Traffic Stats API では、TrafficStats.setThreadStatsTag() を使用して特定のスレッド内のソケットから発生するデータ転送にタグを付けることができます。この関数を呼び出しても、特定のスレッドのすべてのトラフィックが自動的にタグ付けされるわけではありません。タグをソケットに適用する必要があります。

スレッドタグを設定すると、TrafficStats.tagSocket()TrafficStats.untagSocket() を使用して、個々のソケットを手動でタグ付けおよびタグ付け解除できます。タグは、スレッドでソケットが開かれている場合や、サーバー ソケットが接続を受け入れた場合にも適用されます。

複数のスレッドによる同じソケットへの同時アクセスでは、ネットワーク パケットの送受信時にソケットに付けられていたタグが使用されます(バッファリングと再送信のため、ユーザーがデータを読み書きしたときとは異なる場合があります)。

たとえば、次のコードサンプルに示すように、さまざまな種類のネットワーク トラフィックを表す定数を定義できます。

Kotlin

const val USER_INITIATED = 0x1000
const val APP_INITIATED = 0x2000
const val SERVER_INITIATED = 0x3000

Java

public static final int USER_INITIATED = 0x1000;
public static final int APP_INITIATED = 0x2000;
public static final int SERVER_INITIATED = 0x3000;

それに応じて、ネットワーク リクエストにタグを付けることができます。

Kotlin

TrafficStats.setThreadStatsTag(USER_INITIATED)
TrafficStats.tagSocket(outputSocket)
// Transfer data using socket
TrafficStats.untagSocket(outputSocket)

Java

TrafficStats.setThreadStatsTag(USER_INITIATED);
TrafficStats.tagSocket(outputSocket);
// Transfer data using socket
TrafficStats.untagSocket(outputSocket);

HttpURLConnection ライブラリは、現在の TrafficStats.getThreadStatsTag() 値に基づいてソケットに自動的にタグを付けます。また、次のコードサンプルに示すように、キープアライブ プールでリサイクルされる際に、ライブラリはソケットにタグを付けてタグを解除します。

Kotlin

class IdentifyTransferSpikeTask {
    @WorkerThread
    fun request(url: String) {
        TrafficStats.setThreadStatsTag(APP_INITIATED)
        // Make network request using HttpURLConnection.connect()
        ...
        TrafficStats.clearThreadStatsTag()
    }
}

Java

public class IdentifyTransferSpikeTask {
    @WorkerThread
    public void request(String url) {
        TrafficStats.setThreadStatsTag(APP_INITIATED);
        // Make network request using HttpURLConnection.connect()
        ...
        TrafficStats.clearThreadStatsTag();
    }
}

ネットワーク トラフィックのタイプを分析する

アプリによって生成されたネットワーク トラフィックを確認する場合は、トラフィックのソースを把握して適切に最適化する必要があります。アプリが頻繁に発生するネットワーク アクティビティは、ユーザーの操作に応答する場合は完全に適切ですが、アプリがフォアグラウンドにない場合や、デバイスがポケットや財布の中にある場合は、完全に不適切です。

ユーザー開始型トラフィックを分析する

ユーザーが開始したネットワーク トラフィックは、ユーザーがアプリ内で特定のタスクを実行しているときに効率的にグループ化されることもあれば、ユーザーがアプリで取得する必要がある追加情報をリクエストしたときに不均一に広がることもあります。ユーザー開始型ネットワーク トラフィックを分析する目的は、ネットワークを頻繁に使用するパターンを経時的に探し、リクエストをグループ化して頻度を低減することです。

ユーザー リクエストは予測できないため、アプリでのこのタイプのネットワーク使用を最適化することが困難になります。また、ユーザーはアプリを積極的に使用しているときに迅速なレスポンスを期待するため、効率の要求が遅れるとユーザー エクスペリエンスが低下する可能性があります。一般に、ユーザーがアプリを直接操作しているときは、ネットワークを効率的に使用することよりも、ユーザーに対する迅速なレスポンスを優先する必要があります。

ユーザーが開始したトラフィックを最適化するための推奨事項については、ユーザー開始のリクエストを最適化するをご覧ください。

アプリから開始されたトラフィックを分析する

アプリ開始型ネットワーク トラフィックは通常、ネットワーク帯域幅の効率的な使用に大きく影響する領域です。アプリのネットワーク アクティビティを分析する際は、非アクティブな期間を探し、増やすことができるかどうかを判断します。アプリから一貫したネットワーク アクセスのパターンが見られる場合は、このトラフィックをバッチ処理して、アクティビティの期間間でデバイスの無線通信が省電力モードに戻れるようにします。

アプリ開始型トラフィックの最適化に関する推奨事項については、アプリ開始型リクエストを最適化するをご覧ください。

サーバー開始型トラフィックを分析する

サーバーがアプリと通信する際に開始するネットワーク アクティビティも、ネットワーク帯域幅の効率的な使用に大きく影響します。Firebase Cloud Messaging(FCM)は、サーバーから特定のアプリ インスタンスにデータを送信するために使用される軽量なメカニズムです。FCM を使用すると、サーバーは特定のデバイスで実行されているアプリに、利用可能な新しいデータがあることを通知できます。

サーバー開始型トラフィックを最適化するための推奨事項については、サーバー開始型リクエストを最適化するをご覧ください。

Battery Historian を使用してネットワーク トラフィックの影響を可視化する

Battery Historian は、一定期間におけるデバイスのバッテリー消費量を可視化するツールです。このツールを使用すると、ネットワーク アクティビティがバッテリー消費量に与える影響を分析できます。たとえば、Battery Historian は、アプリが想定よりも頻繁にセル無線通信を使用しているかどうかを確認できます。Battery Historian の使用方法については、Batterystats と Battery Historian を使用してバッテリー使用量をプロファイリングするをご覧ください。