LASSIC Media らしくメディア
アプリのバックグラウンド処理実装の進め方
LASSIC IT事業部|元請(プライムベンダー)としてシステム保守・運用を受託
この記事のポイント
- アプリのバックグラウンド処理は、iOSのBGTaskSchedulerとAndroidのWorkManagerという別々の仕組みで実装し、実行タイミングは最終的にOS側が判断します。
- プッシュ通知やフォアグラウンドの常駐処理とは別論点であり、混同すると設計要件を取り違えます。
- 外注する場合は、OSの実行制約を踏まえた設計根拠と、条件未達時のフォールバック方針まで確認する必要があります。
目次
アプリのバックグラウンド処理とは — 前面にない間に動かす仕組み
アプリのバックグラウンド処理とは、ユーザーがアプリを開いていない間に、データの同期やコンテンツの事前取得といった作業をOSの管理下で動かす仕組みを指します。iOSではBackgroundTasksフレームワークのBGTaskScheduler、AndroidではWorkManagerが標準的な実装手段です*1*4。
本稿で扱うのは、この「前面にない間の定期更新・遅延実行・条件付き処理」に限定します。ユーザーへの通知を届けるプッシュ通知(APNs・Firebase Cloud Messaging)や、位置情報の常時取得のようなフォアグラウンド常駐処理は、目的も実装APIも異なる別論点であり、本稿のスコープには含みません。両者を混同して要件定義をすると、発注側と開発側で前提がずれたまま話が進むおそれがあります。
この仕組みの前提として押さえておきたいのが、実行タイミングの主導権がアプリ側ではなくOS側にある点です。開発者ができるのは「いつまでに」「どんな条件で」実行してほしいかをOSに申告することまでで、実際の実行有無やタイミングはバッテリー状況や利用パターンをもとにOSが決定します*1*4。この前提を理解しないまま「毎時決まって動く」といった期待値で設計すると、リリース後に想定通り動かないという問題に直面しやすくなります。
iOSのBGTaskScheduler — App RefreshとProcessingの使い分け
iOSでバックグラウンド処理を実装する場合、BackgroundTasksフレームワークのBGTaskSchedulerを使い、BGAppRefreshTaskとBGProcessingTaskという2種類のタスクを用途に応じて使い分けます*1。
BGAppRefreshTaskは短時間のコンテンツ更新向け
BGAppRefreshTaskは、ニュースの新着チェックのように、アプリが使われる前にコンテンツを静かに取得しておくための短時間タスクです*2。頻繁に使われているアプリほどOSからスケジュールされる頻度が高くなる傾向があり、実行できる時間も短く設計する必要があります。
BGProcessingTaskは長時間の処理向け
BGProcessingTaskは、機械学習モデルの実行やデータベースのメンテナンスなど、数分単位の時間がかかる処理を想定したタスクです*3。リクエストにはrequiresNetworkConnectivityやrequiresExternalPowerといったプロパティがあり、ネットワーク接続や外部電源への接続を条件として指定できます*3。充電中かつネットワーク接続時のみ実行するといった条件付けが可能な点が、App Refreshとの大きな違いです。
どちらのタスクも、事前にInfo.plistのBGTaskSchedulerPermittedIdentifiersキーへ識別子を配列として登録しておく必要があります*1。登録した識別子と、コード上でregisterメソッドに渡す識別子が一致していないと、タスクの登録自体が失敗する仕組みです。実装の起点は「登録」であり、その後にsubmitメソッドでリクエストを送信してスケジュールを依頼するという2段階の流れをたどります*1。
AndroidのWorkManager — 制約(Constraints)と実行保証
AndroidでBGTaskSchedulerに相当する役割を担うのがWorkManagerです。WorkManagerはOneTimeWorkRequestとPeriodicWorkRequestという2種類のワークリクエストを提供し、単発実行と定期実行を使い分けられます*4。
PeriodicWorkRequestの最小間隔は15分
PeriodicWorkRequestで定義できる最小の繰り返し間隔は15分です。これはAndroidのJobScheduler APIと同じ制約であり、それより短い間隔を指定することはできません*4。加えて、指定した間隔が来たからといって即座に実行されるわけではなく、実際の実行タイミングは設定した制約やシステム側の最適化に左右されます*4。
Constraintsで実行条件を細かく制御する
WorkManagerでは、NetworkType(Wi-Fi等の接続種別)・requiresCharging(充電中のみ)・deviceIdle(端末がアイドル状態)・batteryNotLow(低電力状態でない)・storageNotLow(ストレージ空き容量が十分)という制約(Constraints)を組み合わせて指定できます*4。複数の制約を同時に設定した場合、すべての条件が満たされて初めてワークが実行される仕様です*4。たとえば充電中かつWi-Fi接続時のみ大容量データを同期する、といった設計をConstraints.Builderで宣言的に組み立てられます。
iOSのBGProcessingTaskがプロパティで少数の条件を指定する方式であるのに対し、WorkManagerのConstraintsはネットワーク種別からストレージ状態まで対象が幅広く、組み合わせの自由度が高い点が特徴です。
| 観点 | iOS BGTaskScheduler | Android WorkManager |
|---|---|---|
| 主なAPI | BGAppRefreshTask/BGProcessingTask*1 | OneTimeWorkRequest/PeriodicWorkRequest*4 |
| 事前登録 | Info.plistのBGTaskSchedulerPermittedIdentifiersに識別子を登録*1 | Gradle依存関係の追加とWorkerクラスの実装*4 |
| 条件指定 | requiresNetworkConnectivity/requiresExternalPowerなど少数のプロパティ*3 | Constraints(NetworkType・充電・アイドル・低電力・低ストレージ)を組み合わせ指定*4 |
| 定期実行の間隔 | 固定間隔の指定はできず、OSが利用状況から判断*1 | PeriodicWorkRequestは最小15分間隔*4 |
| 実行タイミングの保証 | 保証されない。実行有無・時刻はシステムが判断*1 | 制約充足まで遅延する。Doze等の省電力機構の影響を受ける*5 |
OSの省電力制約(Doze/App Standby等)が実行に与える影響
両OSともバックグラウンド処理は省電力の仕組みと不可分です。設計時にはAPIの使い方だけでなく、この省電力機構がどう作用するかを理解しておく必要があります。
Androidのdozeモードは画面オフ・未接続・静止状態で作動
Androidのdozeモードは、端末が充電されておらず、画面がオフで、一定時間動かない状態が続いたときに作動し、バックグラウンドのCPU処理とネットワークアクセスを遅延させることでバッテリー消費を抑える仕組みです*5。App Standbyは、ユーザーが最近使っていないアプリのバックグラウンドネットワークアクセスを制限する仕組みで、こちらはdozeとは別に働きます*5。アプリの利用頻度や直近の利用状況によって、システムから許可されるバックグラウンド活動の余地が変わってくる点は、開発側が制御できない前提条件として理解しておく必要があります。
iOSも利用パターンに応じてスケジュール頻度が変動する
iOSのBGTaskSchedulerも同様に、システムがバッテリー残量や端末の利用状況を踏まえてタスクの実行可否・タイミングを判断する設計です*1。よく使われているアプリほど優先的にスケジュールされる一方、まったく開かれていないアプリでは長時間タスクが実行されないことも起こり得ます。
この特性が意味するのは、「バックグラウンド処理を実装すれば毎回定期的に動く」という前提そのものが成立しないということです。企画・要件定義の段階で、OS側の実行可否に依存する処理と捉え、実行されなかった場合のフォールバック(アプリ起動時の即時同期など)をセットで設計しておくことが実務上の要点になります。
典型ユースケース(同期・プリフェッチ・アップロード)と設計の勘所
バックグラウンド処理が使われる代表的な場面を整理すると、実装方針の検討がしやすくなります。
データ同期は差分更新を基本にする
サーバー側の最新データをアプリ側に反映するデータ同期は、BGAppRefreshTaskやOneTimeWorkRequestの典型的な用途です。毎回全件を取得するのではなく、差分のみを取得する設計にしておくと、実行時間が短く済み、OSから許可される実行時間内に処理を終えやすくなります。
コンテンツのプリフェッチはユーザー体験の先取り
次にアプリを開いたときに表示するコンテンツを、事前に取得しておくプリフェッチも代表的な用途です。ただし実行タイミングが保証されないため、プリフェッチが間に合わなかった場合でも、アプリ起動時に通常の読み込み処理へ自然に切り替わるフォールバック実装が前提になります。
アップロード処理は制約付きの定期実行と相性が良い
写真や計測データなど容量の大きいファイルのアップロードは、Wi-Fi接続時や充電中のみ実行する制約と組み合わせる用途に適しています。AndroidではConstraintsでNetworkType.UNMETEREDとrequiresChargingを併用し、iOSではBGProcessingTaskのrequiresNetworkConnectivityとrequiresExternalPowerを組み合わせることで、通信量やバッテリー消費を抑えた設計にできます*3*4。
いずれのユースケースでも共通するのは、「バックグラウンドで処理が完了しなかった場合にどう振る舞うか」を先に決めておく設計姿勢です。バックグラウンド処理はあくまで補助的な最適化であり、それに依存しないと成立しない機能設計は避けるのが基本方針になります。
外注時に確認すべき実装範囲と引き継ぎの論点
バックグラウンド処理の実装をアプリ開発会社に外注する場合、OSの制約を踏まえた設計になっているかどうかが品質を左右します。確認しておきたい論点を整理します。
内製に必要なもの
内製でバックグラウンド処理を実装するには、iOSとAndroidそれぞれのプラットフォーム固有API(BGTaskScheduler、WorkManager)への理解に加え、実機での長時間の動作検証体制が必要です。シミュレータや短時間のテストでは、dozeモードやApp Standbyの影響を再現しにくいため、実運用に近い条件での検証工程を組み込めるかが内製可否の分かれ目になります。
発注先への確認
提案書に「バックグラウンド処理を実装します」とだけ書かれている場合、iOS側でBGAppRefreshTaskとBGProcessingTaskのどちらを採用するか、Android側でどのConstraintsを設定するか、実行タイミングが保証されない前提でどのようなフォールバックを用意するかを具体的に質問し、回答の解像度を確認する必要があります。実機での動作検証をどこまで行うかも、事前に確認しておきたい項目です。
契約明記
開発会社との契約が終了した後に運用を引き継ぐ可能性がある場合は、タスク識別子の一覧、Constraints・条件プロパティの設計意図、フォールバック処理の仕様書を納品物に含めるよう契約段階で明記しておく必要があります。これらの資料がないまま引き継ぐと、後任の担当者がなぜその条件を設定したのか分からないまま保守を続けることになり、変更のたびに動作検証をやり直すコストが発生しかねません。
バックグラウンド処理はOSのアップデートによって挙動が変わることもあるため、リリース後も継続的な動作確認が必要な領域です。発注時にはこの保守フェーズまで含めた体制を確認しておくことが望ましいでしょう。
まとめ:バックグラウンド処理を機能させる3つの判断軸
本稿では、iOSのBGTaskSchedulerとAndroidのWorkManagerを用いたバックグラウンド処理の実装について、OSの実行制約を踏まえた設計の勘所を整理しました。要点を3つに集約すると次の通りです。第一に、実行タイミングの主導権はOS側にあり、「毎回定期的に動く」という前提では設計できないため、実行されなかった場合のフォールバックをセットで用意する必要があります。第二に、iOSは少数の条件プロパティ、Androidは幅広いConstraintsという形で条件指定の方法が異なるため、プラットフォームごとの仕様差を理解したうえで用途に合わせる判断が欠かせません。第三に、外注する場合も設計根拠と引き継ぎ資料の範囲を発注前に確認する姿勢が、リリース後の保守品質を左右します。
よくある質問
バックグラウンド処理とプッシュ通知はどう違いますか。
目的も実装APIも異なります。プッシュ通知はサーバー起点でユーザーに情報を届ける仕組みであるのに対し、本稿で扱うバックグラウンド処理はアプリ側がOSにスケジュールを依頼し、データ同期やプリフェッチといった処理を前面にない間に実行する仕組みです*1*4。両者を組み合わせて使うことはありますが、設計上は別の論点として整理する必要があります。
指定した時刻に処理を狙いどおり実行させることはできますか。
できません。iOSのBGTaskSchedulerもAndroidのWorkManagerも、実行の可否とタイミングは最終的にOS側が判断する仕組みであり、バッテリー状況や端末の利用パターンによって遅延したり実行されなかったりすることがあります*1*4。厳密な時刻指定が必須の処理には、この仕組みは適していません。
AndroidのWorkManagerで定期実行の間隔をどこまで短くできますか。
PeriodicWorkRequestで指定できる最小の繰り返し間隔は15分です*4。これより短い間隔を設定することはできず、また間隔が経過したからといって即座に実行されるとも限りません。より短い周期での更新が必要な場合は、別の実装方式を検討する必要があります。
充電中やWi-Fi接続時のみ処理を実行する設定はできますか。
可能です。Androidでは、WorkManagerのConstraintsでNetworkTypeやrequiresChargingなどの条件を組み合わせて指定できます*4。iOSでは、BGProcessingTaskRequestのrequiresNetworkConnectivityやrequiresExternalPowerといったプロパティで同様の条件を指定できます*3。いずれも複数条件をすべて満たした場合に実行される仕組みです。
外注先を選ぶ際に確認すべきポイントは何ですか。
実行タイミングが保証されない前提を理解した上で設計しているか、実機での長時間動作検証を行う体制があるかを確認する必要があります。加えて、タスク識別子やConstraintsの設計意図、フォールバック処理の仕様書を納品物に含めてもらえるかを契約段階で確認しておくと、後の引き継ぎがスムーズになります。
著者:テレリモ総研編集部 鈴木 亮佑
ご不明な点はお問い合わせフォームからもご連絡いただけます。
- *1 出典:Apple「Using background tasks to update your app」(Apple Developer Documentation)https://developer.apple.com/documentation/uikit/using-background-tasks-to-update-your-app
- *2 出典:Apple「BGAppRefreshTask」(Apple Developer Documentation)https://developer.apple.com/documentation/backgroundtasks/bgapprefreshtask
- *3 出典:Apple「BGProcessingTask」(Apple Developer Documentation)https://developer.apple.com/documentation/backgroundtasks/bgprocessingtask
- *4 出典:Android「Define work requests」(Android Developers)https://developer.android.com/develop/background-work/background-tasks/persistent/getting-started/define-work
- *5 出典:Android「Optimize for Doze and App Standby」(Android Developers)https://developer.android.com/training/monitoring-device-state/doze-standby