JobScheduler を使用してジョブのスケジュールを設定しています。主に.setRequiredNetworkType()
、ネットワーク接続 (より具体的には定額制接続) が確立されたときにのみジョブをスケジュールするように指定できるメソッドに使用しています。
次の非常に単純なコードを使用して、ジョブをスケジュールしています。
PersistableBundle extras = new PersistableBundle();
extras.putInt("anExtraInt", someInt);
int networkConstraint = useUnmetered ? JobInfo.NETWORK_TYPE_UNMETERED : JobInfo.NETWORK_TYPE_ANY;
ComponentName componentName = new ComponentName(context, MyJobService.class);
JobInfo jobInfo = new JobInfo.Builder(jobId, componentName)
.setRequiredNetworkType(networkConstraint)
.setExtras(extras)
.build();
JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(jobInfo);
したがって、スケジューリングには 1 つの制約のみが課されます。それは、ネットワーク接続 (「任意」または「非従量制」の場合があります) です。
質問の短いバージョン
すべての制約が満たされ、実際にジョブが実行されるまでの最大遅延を指定するにはどうすればよいですか (たとえば、「ネットワーク接続が確立されてから 2 秒以内にジョブを実行する」など)。
ロングバージョン(とりとめのない)
問題
私が見つけたのは、一部のデバイスでは、ネットワークの制約が既に満たされている期間中にジョブがスケジュールされている場合、ジョブがすぐに実行されることです (または、ユーザーがそのように認識するのに十分な速さで)。
ただし、他のデバイスでは、(ジョブをすぐに実行できるように) 適切なネットワーク接続が既に利用可能であっても、実際に実行されるまでにかなりの遅延が発生します。したがって、これがユーザーの操作に応じたものである場合、何も起こっておらず、アプリが壊れているという印象を受けます。
さて、私はこれがおそらく意図したものであることを十分に認識していJobScheduler
ます...他の要求に最適に適合するようにジョブをスケジュールするのはシステム次第であり、すべての制約がある場合にジョブがすぐに実行されるという保証はありません満足しています。
しかし、必要に応じて、それをある程度制御できると便利です。したがって、ユーザーの関与なしにスケジュールに従って実行されるジョブの場合、システムが正確なタイミングを完全に制御できるようにすることは問題なく、良いことです。
しかし、ジョブがユーザーのアクションに応答する場合、ネットワーク接続が存在すると仮定して、遅延なくジョブを実行したいと考えています。(接続がない場合は、ネットワーク接続が復元されたときにアクションが実行されるというメッセージが表示され、JobScheduler
ネットワークが復元されたときにジョブが確実に実行されるようにします。)
setOverrideDeadline() は解決策ではありませんか?
JobInfo.Builder
メソッドがあることがわかりますsetOverrideDeadline()
。これは、ほとんど私が望んでいるものです。ただし、これは、ジョブがスケジュールされたとき(つまり、すべての制約が満たされていない場合でも 10 秒以内にジョブを実行する) からの最大遅延を指定し、すべての制約が満たされたとき (つまり、すべての制約が満たされてから10 秒以内にジョブを実行する) からではありません。制約が満たされている)。
編集: を使用すると、ジョブが 2 回実行されるという厄介なバグがあるようです:こことここsetOverrideDeadline()
を参照してください。
Firebase JobDispatcher はどうですか?
Firebase JobDispatcherにはTrigger.NOW
トリガーがあることがわかります(「実行時の制約が満たされるとすぐにジョブを実行する必要があることを意味します」)。JobScheduler
これをネイティブにサポートしていない場合、おそらくそれが進むべき道ですか?Firebase JobDispatcher は大ハンマーを使ってナッツを割っているように見えるので、私は先延ばしにされました...そして、Firebase はすべてクラウド メッセージングなどに関するものであり、ローカル タスク スケジューリングからはかけ離れているようです (これは、完全にローカルの問題)。また、Google Play サービスが必要なようですが、これもローカル タスクのスケジューリングにはまったく不要のようです。さらに、Firebase で即時トリガーが可能であり、FirebaseJobScheduler
が Android L+ のみを使用している場合、これを直接実行できるはずです。JobScheduler
Firebase に頼らずに?
編集:私は今これを試しましたがTrigger.NOW
、すぐに応答することを保証するものではありません...実際、私のデバイスではほぼ正確に30秒の遅延があることがわかりました。これは奇妙です.
それに失敗して...
現在、(制約が満たされた場合) 即時実行を保証する唯一の方法は、 を使用しないJobScheduler
ことです。
または、最初の制約チェックを手動で行い、setOverrideDeadline()
すべての制約が満たされている場合は 0 でジョブを実行し、そうでない場合は なしで実行しsetOverrideDeadline()
ます。
. _ JobScheduler
_ setWindow()
_AlarmManager