OSの前提:バックグラウンド処理は基本的に止められる
iOS / Android は以下の理由でバックグラウンド処理を積極的に停止します。
- バッテリー保護(高負荷プロセスは強制停止)
- メモリ確保(バックグラウンド優先度が低い)
- ユーザー操作の見えない処理を抑止するポリシー
そのため、
Flutter の通常実装ではバックグラウンドに移行すると 数分〜20分程度で処理が止まります。
バックグラウンド処理のフロー
+---------------------+
| 計測開始 |
+----------+----------+
|
v
+---------------------+
| フォアグラウンド |
| BLE / GPS / 音声 |
+----------+----------+
|
| アプリがBGへ移行
v
+-------------------------------+
| flutter_background_service |
| - BGタスク起動 |
| - 専用タイマーを回す |
+---------------+---------------+
|
v
+-----------------------------------------------+
| OSによる停止リスク |
| - 高精度GPSによる電池消耗 |
| - 重いDB書き込みによる処理遅延 |
+---------------+-------------------------------+
|
v
+-----------------------------------------------+
| 対策 |
| - GPS: distanceFilterを10mに設定 |
| - 保存: shared_preferencesに一時保存 |
+---------------+-------------------------------+
|
v
+-------------------------------+
| BGでの長時間計測(〜90分) |
+-------------------------------+
OS側で停止が起きるメカニズム(イメージ)
+------------------------------------------------------+
| OSの視点:バックグラウンドアプリ監視 |
+------------------------------------------------------+
|
v
+-------------------------------+
| 高負荷プロセスがないか監視 |
+-------------------------------+
|
YES | NO
(高負荷あり) | (問題なし)
v
+-------------------------------+
| 判定:電池消耗が大きい |
| - 高精度GPS連続利用 |
| - CPU使用率が高い |
+-------------------------------+
|
v
+-------------------------------+
| バックグラウンド優先度を低下 |
+-------------------------------+
|
v
+-------------------------------+
| メモリ / 電池に余裕がない場合|
| → プロセスを強制停止 |
+-------------------------------+
解決:flutter_background_service の導入
バックグラウンドでも処理を継続させるため、
flutter_background_service を使用しました。
- フォアグラウンドサービス化(Android)
- バックグラウンドタスクの実行(iOS/Android)
- Flutter標準の
Timerではなく、サービス側でタイマーを回す構成に変更
これにより、
バックグラウンド移行後も計測ロジックが止まらないようにしました。
iOS の注意点:background_fetch を有効にすると逆に止まる
※iOSでのORPHE TRACKのバックグラウンド動作イメージ
flutter_background_service の README では
「background_fetch を有効に」と推奨されていますが、
ORPHE TRACK のユースケース(長時間の継続動作)では逆効果でした。
-
background_fetch 有効
→ iOSの仕様により 30秒でバックグラウンドタスクが停止
長時間の連続計測が必要な場合は、
background_fetch を有効にしない方が安定しました。
バックグラウンド中のデータ保存問題
ORPHE TRACK では通常、
- データベース(masamune)へランニングデータを保存しています。
しかしバックグラウンドでは、
masamune の保存処理が重く、書き込みに失敗するケースがありました。
- 重い I/O → 処理遅延 → OSの停止判定につながるリスク
解決:shared_preferences を一次バッファとして利用
フォアグラウンド(通常)
+---------------------------------------------+
| GPS / BLE データ |
+-----------------------+---------------------+
|
v
+--------------------+
| masamune(DB)保存 |
+--------------------+
---------- アプリがバックグラウンドへ ----------
バックグラウンド(軽量モード)
+---------------------------------------------+
| GPS / BLE データ |
+-----------------------+---------------------+
|
v
+--------------------------------+
| shared_preferences に一時保存 |
+--------------------------------+
---------- アプリ復帰時 ----------
+---------------------------------------------+
| shared_preferences から読み出し → DB復元 |
+---------------------------------------------+
これにより、
- バックグラウンド中に重い DB 書き込みを避けられる
- アプリが途中で落ちても、計測データのロスを防げる
記事1のまとめ
- Flutter のバックグラウンド処理は OS 仕様により停止しやすい
-
flutter_background_serviceを導入し、サービス側でタイマーを動かす構成に変更 - iOS の background_fetch は「長時間連続処理」には不向き
- バックグラウンド中は heavy I/O を避け、shared_preferences など軽量ストレージを併用する
