無線通信を使用したデータ転送は、アプリのバッテリー消費に大きな影響を及ぼす要因の 1 つです。ネットワーク アクティビティに関連する電池の消耗を最小限に抑えるには、基盤となる無線通信ハードウェアに対して接続モデルがどのような影響を及ぼすかを理解することが重要です。
このセクションでは、無線通信のステートマシンを紹介し、アプリの接続モデルと無線通信のステートマシンの相互作用について説明します。次に、アプリのデータ使用量がバッテリーに与える影響を最小限に抑えるためのいくつかの方法が提示されます。
無線通信のステートマシン
お客様のデバイスの無線通信には、バッテリーの消費量を最小限に抑える省電力機能が組み込まれています。完全にアクティブな無線通信は大量の電力を消費しますが、無効またはスタンバイ状態の無線通信は非常に少ない電力を消費します。
重要な点として、ラジオはスタンバイ状態から完全にアクティブな状態に瞬時に移行することはできません。ラジオの「電源オン」には、レイテンシ期間があります。そのため、バッテリーは、使用していないときに電力を節約し、無線通信の「起動」に伴う遅延を最小限に抑えるために、高エネルギー状態から低エネルギー状態にゆっくりと遷移します。
一般的な 3G ネットワークの無線通信のステートマシンは、以下の 3 つのエネルギー状態で構成されます。
- 最大電力: 接続がアクティブなときに使用され、デバイスは最大転送率でデータを転送できます。
- 低電力: バッテリーの消費電力を約 50% 削減する中間状態。
- スタンバイ: ネットワーク接続がアクティブでないときの最小消費電力状態。
低電力とスタンバイの状態では電池の消耗がかなり少なくなりますが、ネットワーク リクエストに対する遅延が非常に大きくなります。低電力から最大電力の状態に戻るのには約 1.5 秒かかるのに対し、スタンバイから最大電力の状態に遷移するのには 2 秒以上かかることもあります。
遅延を最小限に抑えるには、ステートマシンで低電力のエネルギー状態への遷移を先送りにします。図 1 では、AT&T が測定した一般的な 3G 無線通信のタイミングを使用しています。
各デバイスの無線通信ステートマシン(特に、付随する遷移時遅延(「テールタイム」)と起動時遅延)は、使用されている無線通信テクノロジー(3G、LTE、5G など)によって異なり、デバイスが利用している携帯通信会社ネットワークによって定義と設定が行われています。
このページでは、AT&T から提供されたデータに基づいて、一般的な 3G 無線通信の代表的なステートマシンについて説明します。ただし、一般原則とその結果として得られるベストプラクティスは、すべての無線通信の実装に適用できます。
このアプローチは一般的なモバイル ウェブ ブラウジングに特に効果的で、ウェブ ブラウジング中に発生する望ましくない遅延を防ぐことができます。また、テールタイムが比較的短いため、ブラウジング セッションが終了次第、無線通信は低電力の状態に遷移できます。
残念ながらこのアプローチでは、アプリがフォアグラウンド(遅延が目立つ)とバックグラウンド(電池寿命を優先する必要がある)の両方で実行される Android のような最新のスマートフォン向け OS では、アプリの効率が低下する可能性があります。
アプリが無線通信ステートマシンに及ぼす影響
新しいネットワーク接続を確立するたびに、無線通信は最大電力の状態に遷移します。前述の一般的な 3G 無線通信のステートマシンでは、転送中(およびテールタイムの追加の 5 秒)は最大電力の状態が維持され、その後の 12 秒間は低電力の状態になります。このように、一般的な 3G デバイスでは、すべてのデータ転送セッションにおいて少なくとも 18 秒間、無線通信によって電力が消費されます。
実際面では、たとえば、1 秒間のデータ転送を 1 分あたり 3 回行うアプリでは、無線通信が絶えずアクティブな状態に維持され、スタンバイの状態になろうとするとすぐに最大電力の状態に戻ります。
一方、同じアプリでデータ転送をバンドルし、1 分ごとに 3 秒間の転送を 1 回実行すると、無線通信が最大電力の状態に維持されるのは 1 分あたり合計 20 秒間のみになります。これにより、無線通信が毎分 40 秒間スタンバイ状態になるため、バッテリーの消耗を大幅に抑えることができます。
最適化の手法
ネットワーク アクセスがバッテリー駆動時間に与える影響について理解できたところで、バッテリーの消耗を抑えながら、高速でスムーズなユーザー エクスペリエンスを提供するためにできることをいくつかご紹介します。
バンドル データ転送
前のセクションで説明したように、データ転送を一括化して、より多くのデータをより少ない頻度で転送することは、バッテリー効率を改善するための最善の方法の一つです。
もちろん、ユーザーの操作に応じてアプリがデータをすぐに受信または送信する必要がある場合は、この方法が常に可能であるとは限りません。この問題は、データを予測してプリフェッチすることで軽減できます。ログや分析情報をサーバーに送信する、緊急性のないアプリ主導のデータ転送など、他のシナリオでは、バッチ処理とバンドルが適しています。バックグラウンド ネットワーク転送のスケジュール設定に関するヒントについては、アプリ開始型タスクの最適化をご覧ください。
データをプリフェッチする
データをプリフェッチすると、アプリが実行する独立したデータ転送セッションの回数を効果的に減らすことができます。プリフェッチを使用すると、ユーザーがアプリ内でアクションを実行したときに、後続のユーザー アクションに必要となる可能性のあるデータをアプリが予測して、1 つの接続を最大限に利用して、一気に取得するようになります。
転送を前倒しで行うことで、データのダウンロードの際に必要になる無線通信の有効化の回数を減らすことができます。その結果、電池を節約できるだけでなく、遅延の改善、必要な帯域幅の削減、ダウンロード時間の短縮も実現できます。
また、プリフェッチにより、操作を実行したりデータを表示したりする前にダウンロードが完了するのを待機することで生じるアプリ内遅延を最小限に抑え、ユーザー エクスペリエンスを向上させることができます。
具体的な例を挙げましょう。
ニュース リーダー
多くのニュースアプリでは、カテゴリが選択された後にのみヘッドラインをダウンロードし、ユーザーが記事を読む場合にのみ記事全文をダウンロードし、ユーザーがビューにスクロールしたときにのみサムネイルをダウンロードすることによって帯域幅を削減しようとします。
このアプローチでは、ユーザーがヘッドラインをスクロールし、カテゴリを変更して、それから記事を読むと、そのセッションのほとんどの間、無線通信が強制的にアクティブな状態に維持されます。それだけでなく、エネルギー状態の切り替えが絶えず行われるため、カテゴリを変更するときや記事を読むときに大幅な遅延が生じます。
より良い方法は、起動時に適度な量のデータをプリフェッチすることです。まず、最初のニュースの見出しとサムネイルから始め、低レイテンシの起動時間を確保します。次に、残りの見出しとサムネイル、および少なくともメインの見出しリストから入手できる各記事の記事テキストをプリフェッチします。
もう 1 つのおすすめの方法は、すべてのヘッドライン、サムネイル、記事のテキストに加え、できれば記事の画像もすべてプリフェッチしてしまう方法です。これは通常、あらかじめ決められたスケジュールで、バックグラウンドで行います。ただし、この方法には、使用されることのないコンテンツをダウンロードすることで大量の帯域幅とバッテリー寿命を消費するリスクがあるため、慎重に実装する必要があります。
その他の考慮事項
データのプリフェッチには多くのメリットがありますが、プリフェッチを積極的に使用しすぎると、使用しないデータをダウンロードすることで、電池の消耗が激しくなり、帯域幅の使用量(およびダウンロード容量)が増加するリスクが生じます。また、プリフェッチが完了するのをアプリが待機している間、プリフェッチによってアプリの起動が遅れないようにすることも重要です。具体的に言うと、データを着実に処理し、あるいは連続した転送を優先して開始して、アプリの起動に必要なデータを最初にダウンロードして処理するようにします。
どれだけ積極的にプリフェッチするかは、ダウンロードするデータのサイズと、ダウンロードしたデータが使用される可能性によって異なります。大まかなガイドとして、前述の状態マシンに基づき、現在のユーザー セッション内で使用される可能性が高いデータについては、通常 6 秒間(約 1 ~ 2 メガバイト)プリフェッチできます。この時間を超えると、未使用のデータをダウンロードする費用と、そのデータをダウンロードしないことで得られる費用が同じになります。
一般に、2 ~ 5 分ごとに 1 ~ 5 メガバイトのオーダーで新たにダウンロードを開始するだけで済むようにデータをプリフェッチすることをおすすめします。
大規模なダウンロード(動画ファイルなど)の場合、この原則に沿って定期的(2 ~ 5 分ごと)に分割してダウンロードを行うことで、数分以内に再生される可能性のある動画データだけを効果的にプリフェッチするようにしてください。
解決策の 1 つは、Wi-Fi 接続のときに限り、そして可能であればデバイスの充電中に限り、フル ダウンロードを行うようにスケジュールを設定する方法です。WorkManager API はまさにこのユースケースをサポートしており、デバイスが充電中や Wi-Fi に接続されているなど、デベロッパーが指定した条件を満たすまで、バックグラウンド処理を制限できます。
リクエストを送信する前に接続を確認する
モバイル デバイスにとって、モバイルデータ信号の検索は極めて消費電力の多い処理の一つです。ユーザー開始型リクエストのベスト プラクティスは、接続ステータスと接続測定をモニタリングするに示すように、まず ConnectivityManager
を使用して接続を確認することです。ネットワークが存在しなかった場合、モバイルデータ通信の自動検索を実行しないことで、バッテリーを節約できます。その後、接続時にリクエストをスケジュールし、他のリクエストとともにバッチで実行できます。
接続をプールする
バッチ処理とプリフェッチに加えて役立つ戦略として、アプリのネットワーク接続をプールすることもできます。
一般に、新しいネットワーク接続を開始するよりも既存のネットワーク接続を再利用する方が効率的です。また、接続を再利用すると、輻輳やそれに関連するネットワーク データの問題に対してネットワークがよりインテリジェントに対応できます。
HttpURLConnection
とほとんどの HTTP クライアント(OkHttp など)は、デフォルトで接続プーリングを有効にし、複数のリクエストで同じ接続を再利用します。
まとめと今後の展望
このセクションでは、ワイヤレス無線と、バッテリーの消耗を抑えながら高速で応答性の高いユーザー エクスペリエンスを提供するために幅広く適用できる戦略について学びました。
次のセクションでは、ほとんどのアプリに共通する 3 つの異なるタイプのネットワーク インタラクションについて詳しく説明します。これらの各タイプのドライバと、これらのインタラクションを効率的に管理するための最新のテクニックと API について学習します。