😊

androidのbackground taskについて

2024/12/17に公開

はじめに

androidでバックグラウンドタスクは非常に重要な概念と思います。
不適切な選択肢を取ると色々問題が出てきます。
とはいえすぐに理解するのはなかなか難しく、整理していきたいと思います。

情報元

整理

読む前から自分でも思っていたけど、公式にも「用語の定義が大事!」って書いてある。

用語整理

Some important terms related to background tasks might be used in multiple, contradictory ways. For this reason, it's important to define our terms.
バックグラウンドタスクに関連する言葉は複数の意味で矛盾して使われることがあるので用語を定義するのは大事。

Key Term: An app is running in the background if none of its activities are visible to the user, and the app isn't running any foreground services.
ユーザからアクティビティが見えなくて、foreground serviceを動かしていない場合にそれをバックグラウンドで動いていると言う。

といううことで、foreground serviceはバックグラウンドで動いてはいない!(android用語的に)

If an app is running in the background, the system puts a number of restrictions on it. (For example, in most cases, an app in the background can't launch foreground services.)
バックグラウンドで動作するアプリには制限がかかる。例えばforeground serviceを起動できないとか。

For the purposes of this document, we'll use the term "task" to mean an operation an app is doing outside its main workflow. To ensure alignment in understanding, we've put this into three main categories of types of tasks: asynchronous work, the task scheduling APIs, and foreground services.
このドキュメントではアプリのメインのワークフロー外で動作する操作を意味する時"task"という用語を使います。更に理解を正しくするため、taskを3つのカテゴリーに分けます。非同期work、タスクスケジューリングAPIs、フォアグラウンドサービス、です。

3つのタスクについて

  1. 非同期work
    UIスレッドとは異なるスレッドで動かすものであり。
    UIスレッドで動かすとANRが起きるものであり。
    アプリが終了した時に処理が終了しなくても良いもの。

表のソート処理とか?

  1. タスクスケジューリングAPIs
    ユーザがアプリを抜けてもタスクを継続したい時に最も自由度が高い選択肢。
    ほとんどの場合WorkManagerを使うのが良い選択肢ですが、JobSchedulerを使うほうが良い場合もあります。

WorkManagerを使ったバックグラウンドタスクのシナリオとしては以下などがあります。

  • サーバーからデータを継続的に取得する
  • センサーデータを取得する
  • 位置情報を継続的に取得する(ACCESS_BACKGROUND_LOCATION)権限が必要です
  • コンテンツトリガーで、コンテンツをアップロードします。カメラで撮影した写真などです
  1. フォアグラウンドサービス
    フォアグラウンドサービスは介入されることなく緊急性のあるタスクを実行することができます。しかしながらフォアグラウンドサービスはデバイスに過大な負荷をかける可能性があり、同時にプライバシーやセキュリティへの影響もあります。そのためフォアグラウンドサービスを使うには多くの制限があります。例えば、フォアグラウンドサービスはバックグラウンドからは起動できず、ユーザに動作していることを表示する必要があります。

フォアグラウンドサービスを作るには、Service.startForeground()を呼ぶ方法とWorkManagerを使う方法があります。WorkManagerを使った場合はその他のフォアグラウンドサービスと同じ制限に従う必要があります。

WorkManagerを使ったときのほうが制限が厳しいってことよね。何がどう厳しいのかはまだわからんけど、何かフレームワーク的な制限がある時はstartForegroundを使うことを考えた方が良い感じか。

その他のAPIs

その他に、特定のユースケースに特化したAPIが存在します。もしユースケースにあったAPIがある場合はフォアグラウンドサービスを使わずにそちらを使うことをおすすめします。その方がパフォーマンスが良いでしょう。

例えば、位置情報アップロードのサービスには、GeoFencing用の代替APIがある。

サービス選択チャート

それぞれのタスクの例

  • 非同期work
    SNSのコンテンツ更新。ユーザがスクリーンから離れれば更新の必要はない
  • タスクスケジューリングAPI
    アプリ自体の更新など
  • 短期間フォアグラウンドサービス
    3分以内に終わるフォアグラウンドサービスは特別な権限を必要とせず簡単に作れる。
  • 代替API
    geofence API等

Discussion