web-dev-qa-db-ja.com

Android 8.0-Oreo-API 26でウィジェットを正しく更新する方法

TargetSDKVersionが26に設定されたアプリのウィジェットがあるとします。このウィジェットの更新には100ミリ秒から10秒かかります。ほとんどの場合、1秒未満です。 Android Oの前に、onWidget()がAppWidgetProviderで呼び出された場合、このウィジェットを更新するためにバックグラウンドサービスを起動できました。ただし、Android OはIllegalStateExceptionフォアグラウンドサービスを開始するという明らかな解決策は、99%の時間で10秒以内に行われる何かに対する極端な手段のようです。

可能な解決策

  • フォアグラウンドサービスを開始して、ウィジェットを更新します。 10秒間で消える通知でユーザーを悩ます。
  • JobSchedulerを使用して、できるだけ早くジョブをスケジュールします。ウィジェットはしばらく更新される場合とされない場合があります。
  • ブロードキャストレシーバーで作業を試みます。他のアプリのUIスレッドをロックします。うん.
  • ウィジェットレシーバーで作業を試みます。他のアプリのUIスレッドをロックします。うん.
  • GCMを乱用して、バックグラウンドサービスを実行させます。多くの仕事とハックを感じます。

私は個人的に上記の解決策が好きではありません。うまく行かないと思います。

(さらにイライラするのは、onUpdate()を呼び出すシステムによってアプリが既にメモリにロードされていることです。onUpdate()を呼び出すためにアプリをメモリにロードする方法がわかりませんが、ウィジェット1 UIスレッドはバッテリー寿命を節約します。)

30
Justin

更新トリガーメカニズムが何であるかを示しません。レイテンシーに懸念があるようです(「ウィジェットはしばらく更新される場合と更新されない場合があります」)。そのため、ボタンをタップするなど、ユーザーがアプリウィジェットを操作することに関係があると思います。

JobSchedulerを使用して、できるだけ早くジョブをスケジュールします。ウィジェットはしばらく更新される場合とされない場合があります。

これは「use JobIntentService」のバリエーションであり、この種のシナリオではAFAIKが推奨されるソリューションです。

その他のオプションは次のとおりです。

  • PendingIntentgetForegroundService()を使用します。これにより、ANRの時間枠内でサービスがstartForeground()を呼び出すことを事実上「ピンキー宣誓」します。作業に数秒以上かかる場合は、startForeground()を呼び出してAndroidが不安定にならないようにします。これにより、フォアグラウンド通知が表示される回数を最小限に抑えることができます。 、ユーザーがボタンをタップし、数秒後もまだ仕事をするのに忙しい場合は、おそらくwant通知を表示するか、ユーザーが要求した内容がまだ残っていることをユーザーに知らせるために何かを行う進捗。

  • BroadcastReceivergoAsync()を使用して、メインアプリケーションスレッドを拘束せずにレシーバーのコンテキストで作業します。私はこれをAndroid 8.0+で試したことがないので、YMMV。

10
CommonsWare