-
Notifications
You must be signed in to change notification settings - Fork 113
Fix issue that background task doesn't work in Android. #27
Fix issue that background task doesn't work in Android. #27
Conversation
補足です。 テスト自体は実機(Android 10/Essential PH-1)でも行っています。 |
失礼します。
あと、 ちなみに私の端末では、深夜0時前に COCOA を起動した状態にして放置しておくと、朝までには診断キーがダウンロードされています。 |
@tmurakami @keiji ありがとうございます。XamarinComponents 側 ENのメンテナのMatthew に、個人的に連絡とってみてます。 |
お、いけました。実機だと画面をオフにしてから ちょっと気になったのは、通常使っていて、この状態(idle-maintenance)になるのはどのようなケースかなと。結構テストしたのですが一度もIDLE状態が確認できなかったりします。ぼくは基本的に「充電中はスリープしない設定」にしていますが、今回のテストではそれをオフにしています。 朝までにですか……IDLE移行まで時間がかかるとして、他のアプリが端末を起こしたら待ち直すことになったりすると、一般ユーザーでもなかなかIDLEまで行かない気がします。
これは知りませんでした。リポジトリにファイルが含まれているファイルは上書きのような位置づけになるという理解でいたので……あとから生成できる系とか、ライブラリ(?)に含まれるソースコードは、可能な限りコード管理に含めない方がいい気がしますね。 EDIT:
調べました。
DOZEについては懐かしい話題の一つですが、あらためて。 https://qiita.com/komitake/items/4476e7e4d1b5ed3a8b97 センサーを使って端末の動きも見るとのことで、ぼくがテスト中に場所を動かしたり持ち歩いてたのを検知していた可能性がありますね。 調べた上で、DOZE中は 今回のPRは、 |
@kazumihirose よろしくお願いします!
実際には午前2時前後に動いていることが多いです。 ご指摘の通り当該オプションはとても分かりづらいと思います。 |
I have confirmed that the worker task works better if the constraint `RequiresDeviceIdle` is not set to true.
ec01fd1
to
2a840de
Compare
@tmurakami @kazumihirose メンテナのMatthewからの見解はいかがでしょうか。外部から制約を変更できる手段( |
追試用に @keiji が作った検証コードの Xamarin.Forms 版を置いておきます。 AndroidBackTaskTest/RequiresDeviceIdleTest at main · moonmile/AndroidBackTaskTest |
この変更については開発チームのInternal Repositoryに取り込まれたのでcloseします。 レビュアーのみなさま。ほんとうにありがとうございました。 |
I confirmed that worker tasks do not start if constraints
RequiresDeviceIdle
are set true.Purpose
Fix issue #25
Does this introduce a breaking change?
Pull Request Type
What kind of change does this Pull Request introduce?
How to Test
https://gist.github.com/keiji/4b41890377ab342a48432b38943a0cd3
adb shell dumpsys jobscheduler
Android版で診断キーサーバーとの通信タスクが定期実行されない問題について調査し、原因の一つらしき箇所が見つかったためサジェスチョンとしてのPRとなります。
手元で最小限のコードを作成して実験したところ
WorkManager
のWorkRequest
に制約(Constraints)として、要待機状態(requiresDeviceIdle)を設定すると、Workerが実行されない現象が確認されました。今回
requiresDeviceIdle
を設定した場合に定期実行されない現象については原因は解明できていませんが、現象に対応するため、requiresDeviceIdle
を設定しない(デフォルトでfalse)変更をしています。Googleの公開しているリファレンス実装「exposure-notification-android」の当該部分には
requiresDeviceIdle
がついていません。EN APIの挙動としては当該制約はなくても問題はないという認識です。https://github.com/google/exposure-notifications-android/blob/4b7b461282b2ede6fb2a93488c6d628440052c8d/app/src/main/java/com/google/android/apps/exposurenotification/nearby/ProvideDiagnosisKeysWorker.java#L216-L219
この変更によってバックグラウンドタスクの定期実行が正常に動作するか(#25 (comment) と合わせて複合的な要因である可能性もあります)。
あとはアイドル時以外でも実行されることが、アプリとしてのCOCOAの要件を満たすかと言う話になってくると考えます。
検証方法
検証のため、COCOAのコードからWorkManagerに関連した部分を確認して、最小限で動作する検証コードを作成しました。
結果、ぼくの手元の端末では
requiresDeviceIdle
をtrue
に設定した場合にWorkerが実行されない現象が確認されました。検証用のコードをGistに置いておきます(コードはXamarinのものですが、Androidネイティブで同様のものを作成して実験することもできます)。
https://gist.github.com/keiji/4b41890377ab342a48432b38943a0cd3
WorkManagerは、Androidのバックグラウンドジョブを実行するライブラリで、その実体はJobScheduler(API Level 23以上の場合)です。
JobSchedulerでは
setRequiresDeviceIdle
の注意事項として「端末そのもののIDLEや省電力(DOZE)モードとは関係がなく、直接使われていない場合にジョブの実行を許可する」とあり、IDLEの定義は明確になっていません。https://developer.android.com/reference/android/app/job/JobInfo.Builder#setRequiresDeviceIdle(boolean)
WorkManagerのデバッグ方法はAndroidの公式サイトで紹介されています。
https://developer.android.com/topic/libraries/architecture/workmanager/how-to/debugging?hl=ja
そこで、Android(API Level 28)のエミュレーターに検証用のアプリをインストールして、
requiresDeviceIdle
をtrue
のパターンでコマンドadb shell dumpsys jobscheduler
を実行したところ「IDLE制約を満たしていない」ため実行されない(Unsatisfied constraints: IDLE [0x4])という結果が得られました。どのような状態がIDLEかは明確でないため、エミュレーターの電源ボタンを押して表示を消したり、
adb shell dumpsys deviceidle force-idle
を用いてエミュレーターを強制的にIDLE状態に設定したりしましたが、IDLE制約を満たしてWorkerが実行されることはありませんでした。参考
他にも
setRequiresDeviceIdle
について触れられているIssueが見つかっているので参考までに。