Oreoのバックグラウンド処理制限に直面した話

targetSdkVersionを26に更新する期限が迫ってきたこともあり、趣味で作っているアプリを改修しています。その中でOreoの制限に引っかかって実装を変えることになったので原因と対処法を書き残しておきます。
直面した問題
とあるアプリでバックグラウンドにいるときにサーバーと通信してデータを先読みする、という処理をしていました。
実装上は
- AlarmManagerで定期的にIntentServiceを起動
- IntentService内で通信やDB書き込みなどの長めの処理を実行
といった感じ。
ところが、バックグラウンド実行制限 | Android Developers にあるようにOreoからはバックグラウンド処理の制約がかなり厳しくなっています。
今回は『アプリがバックグラウンドにいる状態でバックグラウンドなサービスは実行できない』というところに引っかかってしまいました。
対処
JobSchedulerを使うのが正攻法のようです。ただ、JobSchedulerはAPI level 21からしか対応してないんですよね。
バージョンに合わせた分岐を自前で書くのはなあ、と思っていたらWorkManagerがピッタリだということが分かりました。
WorkManagerは「バックグラウンド処理をベストプラクティスに合わせてよしなに実行してくれる」ライブラリ。Android Architecture Componentsの一つです。1回だけの実行にも定期実行にも使えますし、バージョンに合わせてJobSchedulerやAlermManagerなどを適切に使い分けてくれます。
バッチリ!と思ったのですが、さらに調べてみると難点も見つかります。
- まだalpha版
- ググると不具合報告らしきものがちらほらと
- 品質面で万全、とは言えないかも
- 依存ライブラリが大量にある
- RoomなどのAndroid Architecture Componentsをふんだんに使っています
- Proguardを適用すればバイナリサイズはさほど膨らまないようです
今回の当該機能は「あると嬉しいけどなくてもアプリとして成立する」ものなので、品質面で多少難があってもいいと判断してWorkManagerを採用しました。
バックグラウンド処理がアプリの肝になる場合は他の方法も検討するか念入りにテストするかしたほうがいいと思います。
クックパッドさんみたいにAndroid4系をサポート外とする、という判断もあり得ますね。そうすればJobSchedulerが使えますし。
参考URL
- Android Oからのバックグラウンド・サービスの制限事項を実演する。
- Android O からの Service を foreground で動かすときのベストプラクティス - Infinito Nirone 7
- Android Developers Blog: Modern background execution in Android
- Jobschedulerの基本
- お前たちのJobSchedulerの使い方は間違っている
- WorkManager - Speaker Deck
- I/O 2018 Codelabs で WorkManager を学習したメモ
- Adding Components to your Project | Android Developers
関連(するかもしれない)記事
おススメ