この記事は Caren Chang による Android Developers Blog の記事 "MAD Skills WorkManager : Wrap-Up" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
WorkManager についての MAD Skills ミニシリーズが終わりました。初めてこのライブラリを使う方のために WorkManager を紹介し、WorkManager のコードのテストやデバッグを行う方法など、高度な使い方へと話を進めました。シリーズ最後のエピソードでは、GCMNetworkManager や FirebaseJobDispatcher を使った古いコードの代わりに WorkManager を使う方法を説明しました。
この記事では、紹介した内容について簡単にまとめます。
最初のエピソードでは、WorkManager Codelab を題材に WorkManager の基本について説明しました。まずは、必要な作業を定義する方法と、その作業をスケジュールする方法について学びました。次に、種類の異なる作業(重複しない作業と定期的な作業)を実現する方法に進みました。WorkManager がどのように作業をスケジュールするかについて理解を深めるため、エピソードの最後では App Standby Bucket について説明しました。
初めて WorkManager を使う方には、以下の記事(英語)も確認することをお勧めします。
続いて、WorkManager がマルチスレッドをどう扱うかについて Ben が詳しく説明しました。スレッドを使う場合は、Executor、コルーチン、RxJava のいずれかを使うことができます。Ben は、WorkManager でそれぞれのアプローチを利用する方法についてデモを行いました。エピソードの最後では、作業が完了したときに結果を返し、UI を更新できるようにする方法を紹介しました。
WorkManager とコルーチンを組み合わせて使いたい方には、Florina が公開したこちらのブログ記事(英語)もご覧ください。
エピソード 3 では、WorkManager の初期化をカスタマイズする方法と、複数のプロセスにまたがるアプリをサポートする方法について説明しました。デベロッパーの皆さんから、テストやデバッグに関するたくさんの質問が寄せられたので、Ben はワーカーをテストする方法や役に立つデバッグ テクニックも紹介しました。
最後のエピソードでは、古いジョブ スケジュール ライブラリ(GCMNetworkManager と FirebaseJobDispatcher)から WorkManager に移行する方法を取り上げました。ターゲット API レベルが 30 以上のアプリでは、Android Marshmallow(6.0)以降を実行しているデバイスで GCM NetworkManager と FirebaseJobDispatcher が動作しなくなります。まだどちらかのライブラリを使っている方は、WorkManager を使うようにアプリをアップデートしてください。
Android GDE の Hugo Visser さんが、最近携わった変更管理アプリで WorkManager を使うことにした理由と、開発プロセスでこのライブラリがどう役立ったかについて話してくれました。
シリーズの最後は、私たちが皆さんから寄せられた WorkManager 関連の質問に答えるリアルタイム Q&A セッションを行いました。WorkManager の今後の計画や、重複した作業の扱い、失敗した作業の再試行などの質問に対する回答をご覧ください。
この記事は Ben Weiss による Android Developers - Medium の記事 "Using WorkManager in multi-process apps" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
📝 WorkManager 2.5.0 をリリースしました。マルチプロセス環境で簡単に使えるようになり、さらに、安定性の改善もいくつか行われています。複数のプロセスを管理するアプリでバックグラウンド作業を確実に管理する必要がある場合は、新しい WorkManager 2.5.0 をお使いください。
利用するためには、コードにいくつかの変更を加える必要がありますので、詳しくご説明します。また、本記事の最後に、今回のバージョンの WorkManager ライブラリにおけるその他の動作の変更点および最新の追加機能を記載していますので併せてご覧ください。
新しいマルチプロセス アーティファクトでは、ジョブのスケジュール管理を 1 つのプロセスに統合することで、パフォーマンスを向上させています。この機能を使うには、まずアプリに追加します。
implementation "androidx.work:work-multiprocess:2.5.0"
これで、WorkManager が WorkRequest をキューに追加するために使う専用のプロセスを選び、プロセス内スケジューラを実行できるようになります。
Configuration.Provider を使って設定する方法は次のようになります。
class MyApplication() : Application(), Configuration.Provider { override fun getWorkManagerConfiguration() = Configuration.Builder() .setProcessName("com.example:remote") .build()}
注: setProcessName のパラメータには完全修飾プロセス名を渡す必要があります。具体的には、アプリのパッケージ名にコロンを付け、その後にホストのプロセス名を指定します。例: com.example:remote
work-multiprocess を使う場合は、WorkManager の代わりに RemoteWorkManager を使って作業リクエストを管理できます。RemoteWorkManager は、常に専用プロセスにアクセスして作業をキューに格納します。これにより、呼び出し側のプロセスで誤って新しい WorkManager を初期化してしまうことはなくなります。プロセス内スケジューラも、同じ専用プロセス内で実行されます。
このように WorkManager を設定し、RemoteWorkManager を使って作業をスケジュールすることで、ジョブを高速に管理し、マルチプロセス アプリの信頼性を高めることができます。指定するプロセスで WorkManager インスタンスが 1 つだけ実行され、ファイルベースのロックを使わなくてよくなるため、SQLite 接続の数を大幅に削減できることに加え、プロセス間でジョブを調整する必要がなくなるためです。
これまでは、ActivityManager が JobService のインスタンスを作成してジョブを開始することができなかった場合、ベースとなるプラットフォームのバグの影響で、そのジョブは破棄され、何の通知も行われませんでした。今回より、WorkRequest オブジェクトとジョブを調整して Application インスタンスが作成されると、WorkManager はすべての WorkRequest についてスケジューラ ジョブが存在することを確認します。
アプリがクラッシュする原因の 1 つは、デバイスのストレージ不足であることがわかりました。これが起きるのは、主に最初からストレージ容量が少なかったデバイスです。しかし、アプリが大量の作業をスケジュールする場合、WorkManager がデバイスのストレージ不足の原因になることもありました。
完了したジョブはデフォルトで 7 日間内部 WorkManager データベースに記録されていました。今回、それが 1 日間に短縮されたので、データベースのサイズが大幅に減少します。
バッファの期間は短縮されますが、ジョブを記録する期間は keepResultsForAtLeast() API を使って制御できます。
WorkManager と ListenableFuture を併用すれば、テストがさらに簡単になります。TestListenableWorkerBuilder Kotlin 拡張機能が、ListenableWorker を拡張したすべてのクラスを受け取れるようになり、テストの柔軟性が向上しています。
今回のリリースには、新機能に加えていくつかのバグの修正も含まれています。これにより、WorkManager の安定性、信頼性、パフォーマンスが向上します。すべての変更点と修正されたバグは、リリースノートで確認できます。
WorkManager を含め、いくつかの Jetpack ライブラリは GitHub からの貢献を受け付けています。Alan Viverette が、プロセス全体について説明しているブログ記事(英語)を書いています。
2.5.0 リリースで修正されたバグのほとんどは、パブリック Issue Tracker で寄せられたものです。
修正につながる問題を登録するコツは、再現できる問題を登録することです。問題の再現に役立つように、WorkManager のサンプルを使うか、問題の説明に手順を記載して独自のサンプルコードを提供することをお勧めします。
ぜひこの機会に作業に着手し、アプリでこのライブラリのバージョンをアップデートしてください。