もうダメアプリなんて呼ばせない!「電池バカ食い」を防ぐAndroid開発のコツ

2017/01/27

Valdio Veliu

27

Articles in this issue reproduced from SitePoint
Copyright © 2017, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2017, KADOKAWA ASCII Research Laboratories, Inc. Japanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria,Australia through Tuttle-Mori Agency, Inc., Tokyo

「バッテリーの減りが異常に早い」「機能の割になぜか通信ばかりしている」——せっかく作ったAndroidアプリがユーザーに嫌われないために、バッテリーやネットワークのリソースを節約する、ちょっとしたコツを紹介。

モバイルアプリ開発の大きな問題が、バッテリー消費量とネットワークデータ消費量です。スマートフォンのリソースは限られているので、以前にも増して問題になっています。

この記事では、バッテリーの駆動時間とネットワークデータ消費量の削減にポイントを絞って解説します。バッテリーの駆動時間を伸ばし、ネットワークデータ消費量を最小限に抑える方法のコツを例を挙げて解説します。

バッテリーの駆動時間を最大にする

もっともバッテリーを消費するハードウェアは、CPU、センサー、液晶画面です。センサーは、GPS、NFC、Bluetoothなどを指します。

バッテリーを消耗するハードウェアを念頭におけば、開発者が注意するべきポイントは簡単に分かります。CPUの利用を必要最小限にしながら、無線通信やネットワーク通信も最小限に抑えるのは難しい作業です。しかし、最高のアプリを目指すなら必要な作業です。

以降、バッテリーの消耗に影響する要素を紹介します。バッテリーの消耗を回避または抑える方法も説明します。

アニメーションの利用に注意する

アニメーションがCPUによる多くの処理能力を必要とし、かなりの電力を消費することは明らかです。
Android デベロッパーのドキュメントによると、ほとんどのアニメーションは1秒あたり30フレームあれば滑らかに見えます。したがって毎秒30フレームを超えるとさらに多くの処理能力が必要となり、より一層バッテリーを消費することになります。

さらにドキュメントによると、アニメーションの間はCPUをスリープ状態にするとよいことが分かります。アニメーションが続くと、デバイスの液晶画面は継続的に変化します。先に述べたように、画面はバッテリーを消耗させる主な要素の1つです。

画像リソース

大きな画像のレンダリングもバッテリーの大幅な消耗につながります。画面に画像を表示することは避けられませんが、大事なことは、必要以上に大きな画像を使用しないことです。

ビットマップ画像の中に切り取っても差し支えない透明ピクセルが含まれている場合は、切り取ることをおすすめします。不必要なピクセルを省くことでパフォーマンスが向上し、バッテリー消費量を減らせます。

WakeLocksの利用に注意する

アプリケーションのタスクは、ユーザーがアプリの画面を開き、実際に操作しているときにだけ実行されているわけではありません。スマートフォンがスリープ状態のときでも動作が必要なアプリもあります。このようなタスクは、スマートフォンがスリープモードの場合、完了できません。

スマートフォンがスリープ状態にあるときにタスクを実行するには、WakeLocksを利用します。WakeLocksは画面やCPUをオン状態にしておくために利用するものです。WakeLocksを利用するシーンとしては、モバイルゲームや動画再生アプリなどがあります。ユーザーがアプリを操作していなくても、スリープ状態に入らずにオン状態を保持します。

WakeLocksの問題点は、間違った使い方をすると、デバイスが長時間オン状態になり、バッテリーやリソースを消費してしまうことです。

WakeLocksの正しい利用方法は、Android Developerドキュメントのガイドラインに従ってください。

バッテリーの効率的な利用戦略

アプリのタスクがクリティカルなものでなく、実行するタイミングを延期してもいいなら、デバイスの充電中に実行するのがよいでしょう。バックグラウンドタスクによくこのようなケースがあります。

デバイスを充電中にタスクを回せば、バッテリーの残量に影響を与えません。たとえば、なんらかのWebサービスとスマートフォンのデータを同期する場合です。

この種のタスクに対する効果的なソリューションとしては、グーグルのJobScheduler APIがあります。このAPIはもっぱら、バックグラウンドタスを効率的にスケジューリングし、ほかのアプリのジョブとともに実行できるようにと開発されたものです。

負荷の大きいタスクを実行する必要がある場合は、このAPIの利用を考えてください。

ネットワーク通信とバッテリー駆動時間の効率化

ここまでバッテリー駆動時間に影響を及ぼす要素の説明をしてきました。しかし、ネットワーク通信は、これまでに紹介したどの要素よりも多くの電力を消費します。ネットワーク通信はバッテリーが消耗するもっとも大きな原因なのです。なんとかして、通信によるバッテリー消費を抑える必要があります。

ネットワーク通信がバッテリーの消費に及ぼす影響を明確に理解するには、ネットワーク通信がリソース利用の観点からどのように実行されているのかを理解することが必要です。ネットワーク通信は無線LANまたは3G / 4G通信の無線を介して実行されます。

エネルギーの消費を抑えるために、Androidシステムは無線機を常にフルパワーにするわけではありません。そうしなければ、バッテリーの駆動時間はすぐに短くなってしまいます。3G無線通信の例をもとにステータスについて説明します。

Radio States

  • Radio Standby:ネットワーク通信が実行されていない。バッテリー消費が抑えられている
  • Radio Low Power:バッテリー電源の50%を使用している中間的な状態
  • Radio Full Power :ネットワーク通信が有効。なんらかのネットワーク通信が実行されている

ネットワークタスクを実行していない場合、無線機はローパワーのアイドル状態に移行し、バッテリー消費量は大幅に減少します。ネットワークに接続すると、無線機はフルパワー状態に移行します。Android Developersドキュメントによると、無線機は接続中ずっとフルパワーを保ちます。さらに5秒間のテールタイム(最長遅延時間)を経て、12秒間ローパワー状態になったあとにスタンバイ状態になります。

たとえば、1回のネットワークタスクが1秒間実行されるとしたら、バッテリーを18秒間も消耗することになるわけです。こう考えると、ネットワーク通信でバッテリーを大幅に消費していることが分かります。

以降で、ネットワーク通信の際、バッテリーリソースの過剰利用を避けるコツや役立つソリューションを紹介します。

バッチ接続

先ほど紹介したように、1回1秒間のネットワークタスクでも実際には18秒分のバッテリーを無駄に消費してしまいます。

そこで、あらゆるネットワーク接続をまとめてグループ化し、次々と実行されるとどうなるでしょうか。そうなれば、無線機はすべてのネットワーク通信で起動からスリープまでの全プロセスを経ることはなくなります。無線機はネットワーク通信が完了するまでアクティブになり、そのあとスタンバイ状態になります。

単純計算すると、1回の大規模なネットワーク通信によって18秒のプロセスを蓄積できます。全体として考えれば、個別にネットワーク通信を実行するよりも、まとめてタスクを実行したほうがアクティブな状態が続く時間が短くなります。

問題なのは、タスクをまとめてグループ化し、フルパワーで実行する必要があることです。しかし、タスクがグループ化されるまで、すべてのリクエストが待ってくれません。この解決策はバックグラウンドタスクに適用すると効果的で、JobScheduler APIが役に立ちます。JobScheduler APIはよりよいリソース活用のために、たくさんのアプリのタスクをグループ化できます。

データを先読みする

通常、アプリを使ってユーザーがなにをするか、どのようなデータをロードするかは予測しがたいものです。しかし、可能であれば、不必要なリクエストを回避するためにできるだけデータをプリフェッチ(先読み)しておくのがおすすめです。

たとえば、オーディオプレーヤーアプリケーションで、キャッシュ機能を備えているなら、再生リストの次のトラックをプリロードしておくことをおすすめします。というのは、ユーザーは次のトラックを再生する可能性が非常に高いからです。

広告はバッテリー消耗の原因要素

モバイル広告は多くのアプリの主要な収入源の1つですが、広告はバッテリー消耗の大きな原因要素です。広告はカラフルな画像や動画を表示するために電力を食うだけでなく、ネットワークを消費します。広告は大規模なコンテンツを読み込むために幅広い帯域を利用し、バッテリーを消耗します。

広告は開発者が収益を稼ぐもっとも一般的な方法なので、モバイルアプリから広告を排除せよと言っているわけではありません。広告を目立ちすぎないようにする、という提案です。バッテリーの消費を抑え、かつ広告からの収益を稼ぐために、広告をアプリの一部だけに限定して表示することをおすすめします。

モニタリングツールを使ってバッテリーを分析する

バッテリーの消費に関してより深く理解するには、アプリに関する統計をモニターしましょう。Android Studioはアプリが消費するリソースを閲覧する、組み込み型のモニタリングツールを備えています。

先に述べたネットワーク通信戦略をもとに、ネットワーク通信がバッテリーに及ぼす影響が目に見えます。以下の画像はネットワークタスクの観点から、ネットワーク通信戦略の良い例と悪い例を示したものです。

Good example

良い例

Bad example

悪い例

良い例は、ネットワークタスクがグループ化されています。悪い例は、ネットワークが散らばっている、悪いネットワーク通信の典型です。

Battery Historian

Battery Historianはグーグルが提供する優れたツールで、Andoroidバグレポートファイルを使ってバッテリーを分析できます。どのプロセスがバッテリーを消耗しているかを表示し、Androidデバイスのバッテリー統計に関する詳細を概観できます。

以下のチャートはバッテリーのモニタリングのために、Battery Historianが提供するデータの例です。

battery-historian/

Battery Historianはオープンソースで、GitHubから手に入ります。

最後に

たくさんのリソースを必要とする大規模なアプリを構築する場合は、バッテリーの効率的な利用最適化が忘れてはいけない課題となります。

この記事で紹介したコツや指針により、ネットワーク通信やバッテリーの効率的な利用について、どこに焦点を絞れば良いかのか理解してもらえれば幸いです。

(原文:Optimizing Battery and Data Consumption in Android

[翻訳:中村文也/編集:Livit

Copyright © 2017, Valdio Veliu All Rights Reserved.

Valdio Veliu

Valdio Veliu

コンピューターエンジニアの学生で、現在「クラウドコンピューティング」内で学士論文を執筆しています。いままでに、C言語、Java、phpなどの言語を学び、最近はJavaやモバイルWeb開発に集中して取り組んでいます。

Loading...