この記事では、JobIntentServiceの1つの問題について説明します。この問題については、Googleバグトラッカーの対応するリソースとレポートに関する多くの質問があります。 また、すべての点から判断すると、Googleはそれをバグと見なさず、これらのレポートを閉じた理由についても説明します。
はじめに
JobIntentServicesはバックグラウンド作業用に作成されました。 バックグラウンドでサービスを使用する機能がなくなったときに、Android 8以降で広く使用されていました。
実際、それらはバックグラウンドでサービスを置き換え、タスクスケジューラ(JobScheduler)の制御下にあります。
このように、システムにはバックグラウンドでタスクの進行を制御する機能があり、ウェイクロック自体も制御するため、デバイスのバッテリー消費を最適化し、開発者がウェイクロックを誤って使用することを回避できます。 これらの手順により、デバイスがスリープモード(Dozeモード)に突入できない状況を最小限に抑えることができました。
JobIntentServiceについて簡単に
本質的に、JobIntentServiceは、タスクスケジューラ(JobScheduler)の制御下にある同じIntentServiceです。
AsyncTaskのバックグラウンドスレッドで実行中。
Android 4.4以前のバージョンでは、通常のIntentServiceが使用されます。
ライフサイクルと落とし穴
両方のタイプのタスクのライフサイクルは同じです。 タスクはハンドラーによって制御され、状態があります。
これらの状態は外部からはアクセスできませんが、特定の状況では、システムが例外をスローし、アプリケーションがクラッシュします。 これらの動作は問題であり、多くの開発者にとって頭痛の種であり、残念ながら単純な解決策はありません。 まず、タスクのステータスとライフサイクルを調査してから、考えられる解決策を検討します。
タスク状態シーケンス
バインド-タスク作成状態(サービスバインディング)タイムアウト18秒。
STARTING-タスクの起動状態、タイムアウト8秒。
EXECUTING-タスク実行状態、タイムアウト10分。
STOPPING-タスクの停止状態(たとえば、cancel()が呼び出された後)、タイムアウトは8秒です。
FINISHED-完了したタスクの最終状態、タスクライフサイクルの最後の状態。
簡素化されたタスクライフサイクル図
各タスク状態には独自のタイムアウトがあります。 タイムアウト後、タスクはステータスに関係なく中断されます。 実際、これはタイムアウトのメカニズムであり、落とし穴です タイムアウト後、システムはjava.lang.SecurityException
型の例外をスローし、次のメッセージが表示されてアプリケーションがクラッシュします。 Caller no longer running, last stopped +1s600ms because: timed out while starting
例外がスローされた瞬間、および「理由」( because: timed out while starting
)-タイムアウトが期限切れになったときのタスクの状態を示します。
結論
経験からわかるように、これらの例外はかなり負荷の高いアプリケーションで見られます。
この問題をサポートするために、脆弱なデバイスとトップデバイスの両方で観察できます。 この問題は、タイムアウトメッセージでスローされた例外によっても示されます。 したがって、たとえば、複数のJobIntentServicesが並行して開始される状況を回避するために、アプリケーションのアンロードとJobIntentServicesの使用の最適化に関する決定は、それ自体を示唆しています。 2番目の解決策は、場合によっては最初のオプションよりも簡単で、時には複雑になることがありますが、JobServiceを使用することです。
また、この問題をグーグルで検索すると、この問題を解決するためのその他の「疑わしい」オプションを見つけることができます。たとえば、次のリンクを参照できます。
PS
現時点では、GoogleはJobServiceとJobIntentServiceの適切な代替品を準備しています-これはandroidx.workパッケージのWorkerとWorkMangerです。
残念ながら、これらのツールはまだ生産の準備ができておらず、多くのバグがありますが、すでにテストで示されているように、これらのツールは上記の問題を解決します。