Flutterで定期的に、例えば15分とか1時間置きにとか、実行する処理を実装するにはどうしたらいいのかの検討。
ネイティブなAndroid側ではたぶん調べつくされたものなのかもしれないけど、その開発環境でプログラムの実装はしたことないため、でそこらあたりは大目に見てもらいたい。
プログラムの構成
実装に関してはgithub側にアップしてある。
プログラムは、一定間隔事にUI側の関数を呼び出し、呼び出された関数側で前回呼び出された時間からの経過時間と現在の時間をListViewに表示するといった簡単なもの。
表示としては上のような感じ。
関数の呼び出しのため、使用するクラス、パッケージは以下の様にしている。
- Timer(クラス)
- android_alarm_manager_plus(パッケージ)
- workmanager(パッケージ)
-
flutter_background_service(パッケージ)
パッケージ機能は別スレッドの関数が呼び出されるため、UI側にはReceivePort経由で関数の呼び出し処理をするようにしている。
また、以前タイマーアプリでDoze対策をした時に指定したバッテリー最適化をOFFにする処理も入れてある。
バッテリー最適化をOFFにしておかないと、スリープ中UI側が全く動作しないため評価にならない。
結果
評価した実機はOPPO A73。
中華系の機器にはスリープ中バッテリー使用量が多くなると問答無用でKillされるということらしいので、たぶん根本的な対応は難しいのかもしれない。
テストは15分間隔でUIを起動するのだけど、UI側で次回起動の時間を再設定する方法と、periodic系メソッドを使う2種類を試している。
Timer
- 非periodic
- periodic
どちらも定期的ではない。
不思議なのは、しょっぱなが900秒近傍以上ではなく600秒近傍になっている点。
明らかに設定値から小さい数値の方に逸脱しているし、どういった理由からなのだろうか。
設定時間に比べ過少な時間で関数が呼び出される理由については判明させることはできなかった。
android_alarm_manager_plus
periodic系であれば、ほぼ指定した時間にUI側の起動が行われている。
- 非periodic
- periodic
ただperiodicでもUIの処理回数(処理時間)が増えたからなのか、アプリがシステムからKillされてしまったときもあった。
workmanager
- 非periodic系
- periodic系
どちらも処理される時間が一定にならない。
flutter_background_service
これに関しては、非periodic系もperiodic系もいつの間にかアプリケーションがKillされていて評価にならなかった。
スリープ中で定時処理をするというには向かないのかもしれない。
結論
Android系で使用するにはandroid_alarm_manager_plus一択になるんだろうか。
ただし、アプリがKillされることを前提とした処理をしなければいけないかも。いわゆるレジューム処理みたいなもの。
また先般書いた中華系機種ではKillされるという情報が掲載されたところには、自動スタートの設定をしておく必要があるという記述もあった。
iOS側に関しては開発環境がないので不明なのだけどそちらはworkmanager何だろうか。
実際の実装では、インターバル処理を行うためのインターフェースを起こし、機種ごとにクラスを作成しそれを呼び出すという感じなのだろうか。
一応今回作ったサンプルプログラムもそういう感じな設計にしてはいるけど。
コメント