

Androidのフォアグラウンドサービス起動、5秒以内にstartForeground()を呼ばないとANRになる
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
Android 8.0(API 26)以降、バックグラウンドのアプリはサービスを直接起動できなくなって、startForegroundService()を使うことになった。このとき、サービス側で5秒以内にstartForeground()を呼ばないとシステムがサービスを止めてANR扱いにする、という制限がある。
何が起きるか
流れはこう。
- 呼び出し元が
startForegroundService()を呼ぶ - システムがサービスを作成する
- サービスの
onCreate()またはonStartCommand()内で5秒以内にServiceCompat.startForeground(...)を呼ぶ - 呼ばなかった場合、
ForegroundServiceDidNotStartInTimeExceptionでクラッシュする
sequenceDiagram
participant Caller
participant System
participant Service
Caller->>System: startForegroundService()
System->>Service: onCreate() / onStartCommand()
Note over Service: ここから5秒以内
Service->>System: startForeground()
alt 5秒以内に呼んだ
System-->>Service: フォアグラウンド化成功
else 5秒超過
System-->>Service: ANR (ForegroundServiceDidNotStartInTimeException)
end
onCreate()で重い初期化処理(DBオープン、ネットワーク接続、大きめのオブジェクト生成など)をやってからstartForeground()を呼んでいると、この5秒に間に合わなくて落ちる。対策は単純で、startForeground()を真っ先に呼んでから、重い処理は後回しにする。
Android 12以降の変更点
Android 12以降は、短時間で終わるフォアグラウンドサービスについてはシステムが通知の表示を10秒待つようになった。setForegroundServiceBehavior()にFOREGROUND_SERVICE_IMMEDIATEを渡すとこの挙動をオプトアウトできる。ただしこれはあくまで「通知がユーザーに見えるタイミング」の話で、startForeground()自体を5秒以内に呼ぶという制約がなくなったわけではない。
WorkManager経由の場合も同じ
WorkManagerでsetForeground() / setForegroundAsync()を使ってフォアグラウンドサービスを立てる場合も同様に、速やかに呼び出す必要がある。2つのフォアグラウンドワーカーのライフサイクルが重なる(片方がシャットダウン中にもう片方が起動しようとする)とクラッシュするバグがあったらしく、WorkManager 2.10.5でこの問題への対応が入っているとのこと(この修正内容自体は実機未確認)。
ハマりどころ
- API 34以降は
foregroundServiceTypeの宣言が必須。宣言していないとそもそも起動条件を満たさない - API 34以降はサービスタイプごとに個別の権限(
FOREGROUND_SERVICE_CAMERAなど)も必要 - Android 12以降はバックグラウンド状態のアプリからのフォアグラウンドサービス起動自体が制限されていて、
locationやremoteMessagingなど一部タイプを除いて例外的な許可が必要になる
5秒制限そのものはシンプルだけど、周辺のバージョン差分(通知表示タイミング、サービスタイプの権限)が絡むと切り分けが面倒になる。