先に結論:WorkManagerは、アプリを閉じたり端末が再起動したりしても、条件が整ったときに実行したい「延期可能で永続的なバックグラウンド処理」に向いています。データ同期、ログ送信、バックアップ、画像処理のように、今この瞬間でなくてもよいが失敗時には再試行したい処理が代表例です。

一方、音楽再生・ナビゲーション・通話のようにユーザーへ継続中であることを見せながら動かす処理はForeground Service、時刻を軸にしたアラームはAlarmManagerなど、要件に応じて使い分けます。WorkManagerを「指定時刻ぴったりに必ず動かすAPI」と考えないことが最初のポイントです。

WorkManagerとは?

WorkManagerはAndroid Jetpackのライブラリで、信頼性が必要なバックグラウンド作業をWorkRequestとして登録し、システムが実行できるタイミングで処理する仕組みです。公式ドキュメントでは、アプリを離れた後やプロセス終了、端末再起動をまたいでも完了させたい永続的な作業のために使うAPIとして説明されています。

作業は主にWorkerやCoroutineWorkerへ実装し、OneTimeWorkRequestで1回の処理、PeriodicWorkRequestで繰り返し処理を表します。WorkManagerは「いつでも即時実行」を保証するのではなく、制約とOSのスケジューリングに従って実行します。

WorkManager・Foreground Service・AlarmManagerの違い

方式向いている処理注意点
WorkManager延期可能で、再起動後も完了させたい同期・ログ送信・定期処理実行時刻はOS・制約次第。即時性は保証されない
Foreground Service音楽、ナビ、通話、大容量転送など、ユーザーが継続中と認識する処理通知、サービス種別、権限、起動制限が必要
AlarmManager時刻を基準にしたアラームやリマインダー正確なアラームには追加要件があり、通常の定期同期の代用品ではない
通常のServiceアプリプロセス内で短時間だけ行う処理プロセス終了やOS制限をまたぐ永続処理の基盤にはしない
WorkManager、Foreground Service、AlarmManager、Serviceの選択フローを示すオリジナル図解
処理の性質から方式を選ぶための整理

長時間処理やForeground Serviceのtype・権限は別の論点です。詳しい制限はForeground Serviceの記事で扱っています。WorkManagerで代替できる延期可能な処理までForeground Serviceにしないよう、まず方式を選びます。

WorkManager 2.12.0の確認ポイント

公式のリリースページでは、WorkManager 2.12.0が2026年9月23日に公開されています。2.11.0からの重要な変更として、minSdkがAPI 23からAPI 24へ変更され、新しいandroidx.work:work-analyticsで実験的なWork Metrics APIを扱えるようになりました。既存アプリで更新する場合は、minSdk、compileSdk、他のAndroidX依存関係との整合性をビルド前に確認してください。

dependencies {
    implementation("androidx.work:work-runtime-ktx:2.12.0")
    // 必要な場合だけ work-analytics などを追加
}

上のバージョンは公式リリースページを確認した時点の例です。プロジェクト全体の依存関係を無条件に更新するのではなく、互換性とテスト結果を確認して採用します。

最小構成:Workerを作って1回実行する

まずは「処理本体」「WorkRequest」「enqueue」を分けて考えると、制約や再試行を後から追加しやすくなります。以下はKotlinの最小例です。ExampleWorkerやURLは記事用のサンプルで、実際のアプリに合わせて置き換えてください。

class ExampleWorker(
    appContext: Context,
    params: WorkerParameters
) : CoroutineWorker(appContext, params) {
    override suspend fun doWork(): Result {
        return try {
            syncData()
            Result.success()
        } catch (e: IOException) {
            Result.retry()
        } catch (e: Exception) {
            Result.failure()
        }
    }
}

val request = OneTimeWorkRequestBuilder<ExampleWorker>()
    .build()

WorkManager.getInstance(context).enqueue(request)

Result.success()は完了、Result.failure()は再試行しても解決しない失敗、Result.retry()は一時的な通信障害などで後から再実行したい状態に使います。例外をすべてretryにすると無限に近い再試行を招くため、恒久的な入力エラーと一時障害を分けます。

Constraintsで実行条件を付ける

WorkRequestには、実行前に満たしてほしい条件を設定できます。複数指定した場合はすべての条件が満たされるまで実行されません。

val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.UNMETERED)
    .setRequiresCharging(true)
    .setRequiresBatteryNotLow(true)
    .setRequiresStorageNotLow(true)
    .build()

val request = OneTimeWorkRequestBuilder<ExampleWorker>()
    .setConstraints(constraints)
    .build()
条件意味確認ポイント
NetworkType接続済み、Wi-Fiなど必要なネットワーク種別オフライン端末では待機する
BatteryNotLowバッテリー残量が低すぎない省電力状態では遅れる
RequiresCharging充電中だけ実行定期バックアップなどに使う
StorageNotLow空き容量不足では実行しないファイル生成系で確認する

制約は「実行の許可条件」であり、処理の成功を保証するものではありません。実行中に条件が外れた場合も停止・再試行の扱いが変わるため、Worker側で途中状態を安全に扱える設計にします。

再試行とBackoffPolicy

一時的な通信障害などではResult.retry()を返します。WorkManagerはBackoffPolicyに従って再スケジュールします。公式仕様では、最初の再試行までの遅延は10秒未満にできず、LINEARは一定幅、EXPONENTIALは試行ごとに増える方式です。デフォルトは指数バックオフ・30秒です。

val request = OneTimeWorkRequestBuilder<ExampleWorker>()
    .setBackoffCriteria(
        BackoffPolicy.EXPONENTIAL,
        WorkRequest.MIN_BACKOFF_MILLIS,
        TimeUnit.MILLISECONDS
    )
    .build()

サーバーが明確に「再試行してはいけない」と返した場合や、入力値が不正な場合はfailure()としてユーザーへの修正導線を作る方が安全です。

二重実行を防ぐUnique Work

同期ボタンを何度も押したとき、同じ処理が並列に走ると重複登録や競合が起きます。名前付きのUnique Workにすると、同じ名前のWorkに対する方針を明示できます。

WorkManager.getInstance(context).enqueueUniqueWork(
    "data-sync",
    ExistingWorkPolicy.KEEP,
    request
)

KEEPは既存のWorkを残して新規追加を抑え、REPLACEは既存Workを置き換える方針です。どちらが正しいかは、同期の重複を避けたいのか、最新リクエストを優先したいのかで決めます。名前だけを付けても一意性は得られないため、enqueueUniqueWorkなどのAPIと方針をセットで使います。

PeriodicWorkRequestは「毎日決まった時刻」ではない

定期同期やログ送信にはPeriodicWorkRequestを使えます。公式ガイドでは、指定できる最小繰り返し間隔は15分です。ただし、これは実行時刻を固定する機能ではありません。制約が満たされるか、端末の省電力やOSの最適化がどう働くかによって実行が遅れたり、条件が周期内に満たされなければその回が見送られたりすることがあります。

val periodic = PeriodicWorkRequestBuilder<ExampleWorker>(
    1, TimeUnit.HOURS
).setConstraints(constraints).build()

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
    "periodic-sync",
    ExistingPeriodicWorkPolicy.KEEP,
    periodic
)

「毎日午前9時」のような時刻の正確さが目的なら、定期Workだけで解決しようとせず、AlarmManagerや通知設計など別の要件を検討します。WorkManagerの定期処理は、時間帯の中で条件が整ったら実行する同期として設計するのが安全です。

WorkManagerが動かないときにWorkInfo、制約、Unique Work、再試行、OSスケジューリングを順に確認する診断フロー
「動かない」を状態・条件・登録・OSの順に切り分ける

WorkManagerが動かないときの確認順

  1. WorkInfoの状態:ENQUEUEDなら待機中、RUNNINGなら実行中、SUCCEEDED・FAILED・CANCELLEDなら処理結果を確認します。
  2. 制約:ネットワーク、充電、バッテリー、ストレージの条件を端末上で確認します。
  3. Unique Work:同じ名前にKEEPを指定していないか、既存Workをキャンセルしていないか確認します。
  4. retryとBackoff:一時障害のために待機しているだけではないか、恒久エラーをretryし続けていないか確認します。
  5. 実行環境:PeriodicWorkの最小間隔、OSの省電力、アプリのテストビルドとリリースビルドの違いを確認します。
  6. ログと入力:Workerの入口・外部通信・DB処理の前後に必要なログを置き、例外を握りつぶしていないか確認します。

状態は、たとえばgetWorkInfoByIdLiveData(request.id)など公式APIで観測できます。アプリを起動した直後だけ確認して「動かない」と判断せず、WorkInfoの状態と失敗理由を記録してください。

長時間処理はForeground Serviceとの境界を確認

WorkManagerの通常Workerは短時間で完了する処理を前提とし、公式APIリファレンスでは通常のバックグラウンドWorkに10分の実行上限が示されています。長時間処理にはWorkManagerのlong-running worker向けForeground APIを検討できますが、通知、サービス種別、権限、Androidのtarget APIごとの制約が関係します。処理がユーザーに見える継続作業ならForeground Serviceを直接選ぶ場合もあるため、必要条件を確認してから実装してください。

Foreground Serviceを使う場合のAndroid 14以降のtype・権限や起動制限は、Foreground Serviceの実装・エラー対処記事を参照してください。Google Playやtarget APIの更新条件と、WorkManagerの実行設計も別々に確認します。

実装前後のチェックリスト

  • 処理が延期可能か、ユーザーに見える継続処理かを決めた
  • Workerの成功・恒久失敗・一時失敗を分けた
  • NetworkTypeや充電などのConstraintsを必要最小限にした
  • 同じ処理を防ぐ名前とExistingWorkPolicyを決めた
  • PeriodicWorkを正確な時刻のAPIとして使っていない
  • WorkInfoとログでENQUEUED、RUNNING、結果を確認できる
  • 端末再起動、通信断、低バッテリー、空き容量不足をテストした
  • 長時間処理ならForeground Serviceのtype・権限を確認した
  • WorkManager 2.12.0へ更新する場合はminSdk 24の影響を確認した

FAQ

WorkManagerはすぐ実行できますか?

制約がなければ早く実行されることはありますが、厳密な即時実行は保証されません。即時性が重要なら別の方式を検討します。

PeriodicWorkRequestは15分ごとに必ず動きますか?

15分は指定できる最小繰り返し間隔です。実際のタイミングは制約やOS最適化の影響を受けます。

Result.retry()なら必ず再試行されますか?

WorkManagerの再スケジュール対象になりますが、バックオフ、制約、OSのスケジューリングに従います。入力エラーなどはfailureに分けます。

WorkManagerとForeground Serviceはどちらが優れていますか?

優劣ではなく目的が違います。延期可能な永続処理はWorkManager、ユーザーが認識する継続処理はForeground Serviceが基本です。

WorkManager 2.12.0へ上げるときの注意は?

公式リリースノートではminSdkがAPI 24へ変更されています。アプリの対応API、依存関係、テスト端末を確認してから更新します。

まとめ

WorkManagerは、アプリを離れても完了させたい延期可能なバックグラウンド処理を、WorkRequest・Constraints・Worker・再試行の組み合わせで管理するAPIです。まず方式を選び、次に処理をWorkerへ分離し、必要な制約とUnique Workを設定します。PeriodicWorkは正確な時刻ではなく、WorkInfoとログで状態を観測しながら実機で確認することが重要です。

参考:Android Developers:Task scheduling、Define work requests、WorkManagerリリースノート