モバイルOSのバックグラウンド実行制限
常駐アプリが電池を溶かす時代を終わらせた仕組みを理解すれば、通知が届かないバグの原因も切り分けられる。
- 1.iOSはアプリを原則サスペンドし、Background Modes宣言やBGTaskSchedulerによる短時間・機会主義的な実行だけを許可する。
- 2.AndroidはDoze/App Standbyで画面消灯後の端末を段階的に休眠させ、バックグラウンドサービスやブロードキャストを制限する。
- 3.制限の根拠はバッテリとメモリという有限資源の共有問題。常駐サービスは前提から崩れており、Push通知起点の起床モデルに置き換わっている。
なぜバックグラウンド実行が「制限される前提」なのか
デスクトップOSでは常駐プロセスが常識ですが、モバイルOSはこれを原則禁止に近い形へ倒しています。理由は単純で、CPU・無線・GPSを動かし続けるアプリが1つでもあれば、バッテリ駆動時間という共有資源が一部のアプリに独占されるからです。さらにモバイル端末は物理メモリが小さく、複数アプリを同時に生かしたままにするとメモリ不足で強制終了(OOM Kill)が多発します。つまり「バックグラウンドで自由に動けるアプリがある」こと自体が、他アプリの体験とバッテリ持ちを悪化させる負の外部性を生みます。iOSとAndroidは方式こそ異なりますが、どちらも「基本は止める、必要な処理だけOSの管理下で機会的に動かす」という同じ思想に収束しています。
iOS: サスペンドが既定状態
iOSアプリはフォアグラウンドを失うと数秒でサスペンド(実行停止・メモリ上には残存)に入ります。CPU時間は原則ゼロで、コード実行が必要な処理は事前に宣言した種類(Background Modes)だけがOSに許可されます。
| Background Modes種別 | 許可される処理 | 制約 |
|---|---|---|
| Audio/AirPlay | 音楽・通話などの継続再生 | 実際に音を出し続けている間のみ有効 |
| Location updates | 位置情報の継続取得 | 許可レベルとバッテリ消費への配慮が必須 |
| VoIP | 着信待ち受け | PushKitのVoIP通知と組で使用 |
| Background fetch/Processing | 定期的な短時間処理 | 実行タイミングはOS裁量、保証されない |
iOS 13以降、定期的なバックグラウンド処理はBGTaskScheduler経由に統一されています。アプリは「このタスクをだいたいこの頃に実行してほしい」とリクエストを登録するだけで、実際に起動するかどうか、いつ起動するかはOSが決めます。判断材料は端末の充電状態、Wi-Fi接続の有無、ユーザーの利用パターン学習(そのアプリを普段いつ開くか)などで、バッテリに余裕があり有線給電中の夜間などにまとめて実行される傾向があります。開発者が指定できるのはあくまで「早くともこの時刻以降」という下限であり、実行の確約ではありません。
この設計の狙いは、アプリ側の都合ではなくOS側の都合(電力・熱・利用状況)で実行タイミングを一元管理することです。個々のアプリが「自分は重要だから今すぐ動きたい」と主張しても、OSが全アプリの要求を集約し、システム全体の電力予算内に収まるようスケジューリングします。即時性が必須な用途(メッセージ着信など)は、アプリ自身を起こすのではなくPush通知(APNs)でOS側に処理させ、必要なら通知配信と同時にNotification Service Extensionという別プロセスを短時間だけ起動する形で解決します。
Android: DozeとApp Standbyによる段階的休眠
Androidは6.0(API 23)以降、Dozeという端末全体の休眠モードを導入しました。画面が消灯し、充電されておらず、一定時間動きがないと判定されると、段階的にネットワークアクセスとCPUウェイクロックを制限します。
画面OFF + 未充電 + 静止状態が継続
↓
[軽度Doze] メンテナンスウィンドウを一定間隔で開き、
その間だけネットワーク・ジョブ実行を許可
↓
[深度Doze] メンテナンスウィンドウの間隔が指数的に延長
(最初は短く、時間が経つほど間隔が長くなる)
メンテナンスウィンドウの外では、通常のネットワークアクセスは保留され、AlarmManagerの通常アラームも遅延し、JobSchedulerのジョブも実行されません。さらにApp Standbyは、Doze中かどうかに関わらず「最近使われていないアプリ」を個別にバケット分類し、使用頻度が低いアプリほどジョブ実行の機会を絞ります。
| 仕組み | 対象 | 効果 |
|---|---|---|
| Doze | 端末全体(画面OFF・静止時) | ネットワーク・CPUウェイクロックを一括制限 |
| App Standby | アプリ単位(未使用期間で判定) | 使用頻度が低いアプリほどジョブ実行を制限 |
| バックグラウンド実行制限(8.0以降) | バックグラウンドサービス全般 | フォアグラウンド遷移後は明示的なフォアグラウンドサービスのみ継続可 |
Android 8.0(Oreo)以降はさらに踏み込み、アプリがバックグラウンドに回った後は原則としてバックグラウンドサービスの開始自体を禁止し、常駐が必要なら通知を伴うフォアグラウンドサービスとして明示的に扱う必要があります。通知バーに常時表示される「音楽再生中」「経路案内中」のような表示は、ユーザーに見える形にすることで初めて継続実行を許すという設計判断の現れです。暗黙のブロードキャスト受信も同様に制限され、任意のアプリがシステムイベントをトリガーに一斉起床することができなくなりました。
常駐サービスが成立しない理由
かつてのデスクトップ的発想である「サービスを一つ立ち上げておいて、いつでも即座に反応する」という常駐モデルは、モバイルOSの制約下では前提から崩れます。
第一に、無線モデム(Wi-Fi/セルラー)は待機状態と送受信状態の電力差が大きく、CPUがスリープしていても無線だけ起きていれば電池は大きく減ります。ウェイクロックを保持し続けるアプリが1つあれば、端末全体がDozeに入れず、他の全アプリのバッテリ消費にも波及します。第二に、モバイル端末のメモリはデスクトップより小さく、バックグラウンドプロセスを無制限に生かすと新しいアプリ起動時にOSがメモリを確保できません。iOS・Androidともにメモリ逼迫時は優先度の低いバックグラウンドプロセスから強制終了する仕組みを持ち、常駐を前提にした設計はこの強制終了で簡単に破綻します。
この2つの制約があるため、両OSとも「即時性が必要な通知はOSのプッシュ基盤に委任し、アプリ自身は基本サスペンド・休眠させる」というアーキテクチャに統一されました。アプリを常時起こしておく代わりに、サーバー側からOSのプッシュサービス(APNs、Firebase Cloud Messaging相当の基盤)へ通知を送り、OSが受け取った時点でアプリを必要なだけ短時間起床させる。起床の主導権をアプリからOSへ移すことで、電力とメモリの配分をシステム全体で最適化できるわけです。開発者にとっての実務的な帰結は明確で、定期実行が必要な処理は「いつ動くか」を諦めてOSのスケジューラに委ね、即時性が必要な処理はプッシュ通知を起点に設計する、という発想の転換が求められます。
まとめ
iOSはBackground Modesで許可された種別のみを機会的に実行し、定期処理はBGTaskSchedulerを通じてOSの裁量に委ねます。AndroidはDozeとApp Standbyによって画面消灯後の端末とアプリ単位の双方から実行機会を段階的に絞り込み、バックグラウンドサービスの起動そのものを制限します。根底にあるのはバッテリと物理メモリという有限資源をOS全体で公平に配分するという設計思想で、アプリ主導の常駐モデルはこの制約と根本的に相容れません。実行の主導権をアプリからOSのスケジューラやプッシュ基盤へ委ねる設計へ転換したことが、現代のモバイルOSがバックグラウンド実行を厳しく制限する最大の理由です。より広いOSのプロセス管理やスケジューリングの原理は/os/、電力・熱の制約が絡む組込み設計の視点は/embedded/と合わせて理解すると見通しが良くなります。
モバイル開発 Article
モバイルOSのバックグラウンド実行制限を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
モバイル
比較で見る軸
難易度: advanced / カテゴリ: モバイル開発 / タグ数: 5
導入後に効く点
AndroidはDoze/App Standbyで画面消灯後の端末を段階的に休眠させ、バックグラウンドサービスやブロードキャストを制限する。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- モバイル開発
- タグ数
- 5
判断チェックリスト
- 自社の用途が「モバイル / iOS」に近いか確認する。
- 強みである「iOSはアプリを原則サスペンドし、Background Modes宣言やBGTaskSchedulerによる短時間・機会主義的な実行だけを許可する。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。