Background Executionは、モバイルアプリがフォアグラウンドにないときにコードを実行するためのメカニズムです。このメカニズムがないと、アプリを最小化したときにシステムがアプリを一時停止します。Apple(2026年)によると、iOSはバックグラウンド時間を30秒に制限していますが、AndroidはWorkManagerとForeground Serviceを通じてより柔軟なシナリオを提供しています。
重要なポイント
Background Executionとは、ユーザーがアプリを最小化したり別のアプリに切り替えた後も、アプリがコードを実行し続ける機能です。特別なメカニズムがない場合、モバイルOSはバックグラウンドに移行してから数秒以内にアプリをSuspended(一時停止)状態にし、アクティブなアプリのためにCPUとメモリを解放します。
モバイルアプリは、Foreground(アクティブ)、Background(バックグラウンド)、Suspended(一時停止)、Terminated(終了)のいくつかのライフサイクル状態を経ます。Backgroundは、アプリが可視インターフェースなしでコードを実行できる唯一の状態です。iOSとAndroidは、この状態での期間と利用可能な操作を異なる方法で定義しています。
バックグラウンド実行は、データ同期、コンテンツダウンロード、プッシュ通知処理、バックグラウンド位置情報、オーディオ再生に必要です。同期が最も一般的なシナリオです。アプリはユーザーの操作なしでサーバーにデータを送信したり、アップデートをダウンロードしたりします。
バックグラウンド実行の制限は、エネルギー消費、デバイスのパフォーマンス、ユーザーのプライバシーの3つの要因によるものです。CPUと無線モジュール(Wi-Fi、携帯データ)が最も多くのエネルギーを消費します。バックグラウンドプロセスごとにバッテリー寿命が短くなります。
Googleの調査によると、5分ごとにバックグラウンドタスクを実行するアプリは、1日でデバイスのバッテリー寿命を20〜30%削減します。1時間に1回の頻度で最適化されたバックグラウンド操作でも、そのようなアプリが2つ以上あると顕著な影響があります。
バックグラウンドアプリはそれぞれRAMを占有します。RAMが不足すると、システムはメモリからアプリをアンロードし、ユーザーが戻ったときに再起動が発生します。iOSはJetsamアルゴリズムを使用しています。これはメモリ制限を超えたときにバックグラウンドプロセスを強制終了するメカニズムです。Androidも同様の原理でLMK(Low Memory Killer)を使用しています。
Android 10およびiOS 13以降、システムはアプリにバックグラウンド作業の目的を宣言するよう要求しています。AndroidはバックグラウンドでのBroadcast Receiverの起動に制限を導入しました。iOSはプロジェクトのCapabilitiesでBackground Modeを指定する必要があります。ユーザーは設定で任意のアプリのバックグラウンド実行を無効にできます。
| OS | バージョン | 制限 | 影響 |
|---|---|---|---|
| Android | 8.0 | IMPLICIT_BROADCAST禁止 | 67%のバックグラウンドBroadcastが破損 |
| Android | 9.0 | Doze改善 | ネットワーク呼び出し制限 |
| Android | 12+ | Foreground Service制限 | バックグラウンドからの起動禁止 |
| iOS | 7+ | Background App Refresh | 定期的な更新ウィンドウ |
| iOS | 13+ | BGTaskScheduler | 実行ではなくスケジューリング |
Androidはバックグラウンド実行のための複数のメカニズムを提供しており、それぞれ異なるカテゴリのタスクを解決します。WorkManagerは遅延タスクおよび定期的なタスクに推奨されるAPIです。Foreground Serviceは可視通知付きの即時実行のためのものです。JobSchedulerはWorkManagerの低レベルな代替手段です。
WorkManagerはAndroid Jetpackの一部で、デバイスの再起動後でも完了を保証するバックグラウンドタスク実行を提供します。APIはネットワーク状態、バッテリーレベル、Dozeモードを考慮して最適な実行時間を選択します。WorkManagerはAPI 14+と互換性があり、非推奨のAlarmManagerとJobSchedulerを置き換えます。
アプリがユーザーに表示されるタスク(音楽再生、位置情報記録)を実行する必要がある場合、Foreground Serviceが使用されます。サービスはステータスバーに永続的な通知を表示し、優先度が高くなります。システムはタスクが完了するまでサービスを終了しません。Android 13以降、POST_NOTIFICATIONSの許可が必要です。
Android 6.0以降、デバイスはアイドル時にDozeモードに入ります。このモードでは、ネットワーク操作、同期、JobSchedulerが延期されます。WorkManagerはDozeに自動的に適応します。タスクはメンテナンスのためにデバイスがスリープから復帰する次のメンテナンスウィンドウ中に実行されます。
iOSはバックグラウンド実行に対してより厳格なアプローチを採用しています。Background App Refreshは定期的なデータ更新の主要なメカニズムです。BGTaskSchedulerはシステム状態に基づいてタスクをスケジュールするためのAPIです。長時間実行操作には、audio、location、voip、fetch、processingのBackground Modesが利用可能です。
Background App Refreshを使用すると、アプリはデータを同期するために15〜30分ごとに起動できます。起動時間はユーザーの行動によって異なります。システムはユーザーがアプリを開く頻度を分析します。ユーザーは設定→一般→Background App Refreshで個別のアプリのこの機能を無効にできます。
iOS 13以降、BGTaskSchedulerは非推奨のperformFetchとbeginBackgroundTaskを置き換えました。アプリは識別子と最小間隔でタスクを登録し、システムが最適な実行時間を決定します。タスクはBGProcessingTask(長時間、10分以上)とBGAppRefreshTask(短時間、最大30秒)の2種類に分けられます。
iOSはバックグラウンドタスクの実行に制限時間を割り当てます。BGAppRefreshTaskは最大30秒、BGProcessingTaskは最大10分です。制限を超えると、システムはタスクを強制終了します。開発者は中間結果を保存するためにexpiration handlerを呼び出す必要があります。
WorkManagerを使用したAndroidでのバックグラウンド実行の実践的な実装を見てみましょう。ネットワーク状態を考慮した8時間ごとのデータ同期の例です。WorkManagerはデバイスの再起動後でもタスクの実行を保証します。
class SyncWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
return try {
syncDataToServer()
Log.d("Sync", "データが同期されました")
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
// 8時間ごとに定期タスクを実行
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(false)
.build()
val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(
8, TimeUnit.HOURS
).setConstraints(constraints).build()
WorkManager.getInstance(context).enqueue(syncRequest)
ユーザーに表示される長時間操作には、Foreground Serviceを使用します。通知に進捗状況を表示するファイルダウンロードの例です。サービスはdismissできない通知とともにstartForeground()を呼び出します。ダウンロードが完了したらstopForeground(STOP_FOREGROUND_REMOVE)を呼び出します。
class DownloadService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, id: Int): Int {
startForeground(NOTIFICATION_ID, createNotification())
downloadFile()
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
return START_NOT_STICKY
}
private fun createNotification(): Notification {
return NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("ファイルをダウンロード")
.setSmallIcon(android.R.drawable.ic_download)
.build()
}
}
iOSでは、バックグラウンド実行はBGTaskSchedulerを介して設定されます。コンテンツ更新タスクの登録と実行の例です。アプリはInfo.plistにタスク識別子を登録し、タスクをスケジュールする必要があるときにsubmitを呼び出す必要があります。
import BackgroundTasks
func registerBackgroundTask() {
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.app.refresh",
using: nil
) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(
identifier: "com.app.refresh"
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)
}
func handleAppRefresh(task: BGAppRefreshTask) {
scheduleAppRefresh()
task.expirationHandler = {
// 中間データを保存
cacheCurrentState()
}
fetchLatestData {
task.setTaskCompleted(success: true)
}
}
長時間実行操作(キャッシュクリア、データ処理)には、BGProcessingTaskを使用します。システムは実行に最大10分を許可します。デバイスが充電中でWi-Fiに接続されている場合にのみ実行されます。Info.plistに個別の識別子が必要で、register(forTaskWithIdentifier:)を介した登録が必要です。
func scheduleProcessing() {
let request = BGProcessingTaskRequest(
identifier: "com.app.cleanup"
)
request.requiresExternalPower = true
request.requiresNetworkConnectivity = true
request.earliestBeginDate = Date(timeIntervalSinceNow: 24 * 60 * 60)
try? BGTaskScheduler.shared.submit(request)
}
AndroidとiOSは、バックグラウンド実行の哲学において根本的に異なります。Androidはより大きな制御を備えた柔軟なツールを提供しますが、開発者が適切なAPIを選択する必要があります。iOSは機能を制限しますが、安定したパフォーマンスとバッテリー寿命をユーザーに保証します。
| 基準 | Android | iOS |
|---|---|---|
| 推奨API | WorkManager | BGTaskScheduler |
| 最大タスク時間 | 無制限(Foreground Service) | 30秒 / 10分(processing) |
| 定期的なタスク | はい、PeriodicWorkRequest経由 | はい、BGAppRefreshTask経由 |
| 実行保証 | はい、再起動後も | いいえ — システムが決定 |
| バックグラウンドネットワークアクセス | Dozeモードで制限 | background構成のURLSession経由 |
| バックグラウンド位置情報 | Foreground Service + 許可 | Background Mode location + NSLocation |
| バックグラウンドオーディオ | メディア通知付きForeground Service | Background Mode audio + AVAudioSession |
WorkManagerは、アプリの状態に関係なく完了する必要があるタスクに最適です:データ同期、分析データの送信、キューの処理。APIはデバイスのシャットダウン後でも実行を保証します。タスクは起動後に再スケジュールされます。
BGTaskSchedulerは、システムが都合の良いときに実行できるタスクに適しています:新しいコンテンツのダウンロード、ウィジェットの更新、キャッシュのクリア。緊急の操作には適していません — デバイスがDoze状態またはバッテリー残量が少ない場合、システムはタスクを遅延させます。
よくある質問
Background Executionは、バックグラウンドで実行されるコード全般を表す一般的な概念です。Background Modesは、アプリが特定のタイプのバックグラウンド操作(オーディオ、位置情報、VoIP、fetch)を実行できるようにするiOS固有のメカニズムです。AndroidはForeground Serviceのタイプを通じて同様のアプローチを使用しています。
iOSでは、これはBGAppRefreshTaskの標準的な制限です。制限に達すると、システムはタスクを強制終了します。Androidでも、アプリがWorkManagerやForeground Serviceを使用していない場合に同様の状況が発生します。通常のServiceはバックグラウンドに移行するとシステムによって終了されます。
AndroidではWorkManagerを使用してください。再起動後でも実行を保証します。iOSでは実行を保証できません。システムがタスクをいつ実行するかを決定します。実行を保証する唯一の方法は、ユーザーに表示されるインジケーター付きのBackground Modes(audio、location)を使用することです。
iOSではUIApplication.shared.backgroundRefreshStatusを呼び出します。ステータスは.available、.denied、.restrictedのいずれかです。Androidでは、PowerManager.isIgnoringBatteryOptimizations()を使用してバッテリー最適化の免除を確認します。WorkManagerの場合は確認は不要です。API自体がシステムの制限を処理します。
プッシュ通知は、バックグラウンドコードなしでアクションをトリガーする主要なメカニズムです。iOSでは、VoIP用のPushKitとデータ更新用のSilent Pushが利用可能です。AndroidではHigh Priority FCMとNotification Trampolineが利用可能です。Foreground Serviceを介したWebSocketはリアルタイムアプリの代替手段です。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。