最近、Polliからの通知を処理するために作業しているアプリを、通常のIntentServiceではなくJobIntentServiceを使用して更新していました。これは、Lollipop以前のデバイスでもポストでもこれを処理する正しい方法のようです。私はそのような仕事をキューに入れています:
enqueueWork(context, MyJobServiceExtension.class, JOB_ID, work);
これはマニフェスト宣言です:
<service Android:name="com.example.MyJobServiceExtension" Android:permission="Android.permission.BIND_JOB_SERVICE" Android:exported="true" tools:node="replace">
OnHandleWorkのコールバックやlogcatのエラーログを見ることはありません。これを統合できる人はいますか?
更新:APIレベル21のデバイスでこれをテストし、動作しました。しかし、私のAndroid OピクセルXLデバイスで呼び出されるようには見えません。
更新#2:また、インテントサービスのonCreateが呼び出されるように見えますが、他のライフサイクルメソッド(onHandleWorkを含む)はありません。誰もこれに遭遇しましたか?
IntentServiceからJobIntentServiceにアップグレードした後、同じ問題が発生しました。古い実装からこのメソッドを削除してください:
@Override
public IBinder onBind(Intent intent) {
return null;
}
私にとってこれで問題は解決しましたが、今ではオレオの前後で動作します。
私は同じ問題を抱えていました(O以前のデバイスでは問題なく動作しましたが、Oデバイスでは何も起きていませんでした)。今日、昨日とまったく同じコードで再試行しましたが、今は動作します-唯一の違いは、間にデバイスを再起動したことです。
私の現在の理論では、最初のセットアップは機能しませんでした。私の現在のものはそうであり、新しいコードを再デプロイするだけでは、JobSchedulerから壊れた状態がクリアされません。パッケージの再起動またはアンインストール/再インストールが行われます。
現在機能しているセットアップ(以前のIntentServiceから移行):
<service
Android:name=".MyJobIntentService"
Android:exported="false"
Android:permission="Android.permission.BIND_JOB_SERVICE"/>
で始まる
Intent intent = new Intent();
intent.putExtra(EXTRA_NAME, extraValue);
JobIntentService.enqueueWork(context, MyJobIntentService.class, FIXED_JOB_ID, intent);
インテントはnot明示的なインテントであることに注意してください(つまり、ComponentNameは設定されていません)。
JobIntentService
を使用してJobScheduler
をエンキューしようとすると、この問題に遭遇しました。 JobScheduler
には独自のenqueueWork()メソッドがありますが、JobIntentService
では機能しません。サービスは開始されますが、onHandleWork()は呼び出されません。
JobIntentServiceにある静的enqueueWork()メソッドを使用すると、再び機能し始めました-例:
MyJobIntentService.enqueueWork(context, ...)
これは、Androidのjavadocを読んでも明らかではありませんでした。
onCreate
でJobIntentService
メソッドをオーバーライドした場合、onHandleWorkが呼び出されなくなります。
Service
をJobIntentService
に変換しましたが、onCreate
メソッドを削除して初めて機能しました。
これは私のために働いたものです、
@agirardelloが示唆するIBind
オーバーライドを削除します
以下を追加しました
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
これがなぜ機能したのか分かりません。
onHandleWork
からService
に移行した後、2回目にJobIntentService
が呼び出されないという同様の問題に遭遇しました。ログには、enqueueWork
が呼び出されたが、onHandleWork
が最初のみを実行し、スタックしているように見えたことが示されていました。
さらに掘り進んでログを記録したところ、「スタック」シナリオではJobIntentService#onDestroy
onHandleWork
のすべての操作が実行され、一見終了したように見えますが。
原因は、最初のジョブの破棄を妨げていたアクティビティライフサイクルへのそのサービスのbindService
呼び出しであり、何らかの理由で、この条件がサービスの「スタック」を引き起こした後にenqueueWork
次のonHandleWork
を再度実行しないでください。
そのため、最初の呼び出しがJobIntentService
を再びトリガーしないと、onHandleWork
がスタックしたように見える誤ったイベントログがあります。
enqueueWork -> first call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
enqueueWork -> second call
enqueueWork -> third call
JobIntentService
呼び出しを削除した後、bindService
が正しく機能するイベントの正しいログを次に示します。
enqueueWork -> first call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
onDestroy (service is destroyed after the job is finished)
enqueueWork -> second call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
onDestroy
enqueueWork -> third call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
onDestroy
これが誰かに役立つことを願っています。
他の回答で問題を解決できなかったすべての人に:
enqueueWorkが呼び出されるたびに、異なるJOB_IDsを使用してみてください。前のジョブが終了していない場合、サービスがスタックしている可能性があり(ユーザー「git pull Origin」が説明した問題と同様)、別のIDを持つ新しいジョブがこの問題を解決する可能性があります。
私はついにその問題のLoLの解決策を見つけました
「onBind」メソッドをオーバーライドし、「enqueueWork」メソッドを使用して作業を呼び出す場合、これを行う作業のエンジンにバインドを返す必要があります。
@Override @Nullable
public IBinder onBind(@NonNull Intent intent) {
[... Do What You Want ... ]
return super.onBind(intent);
}
したがって、「super.onBind」メソッドのIBinderを返すので、それを使用してJobIntentServiceにバインドする必要があります。
別のバインダーをバインドして返したい場合は、次のようにします。
@Override @Nullable
public IBinder onBind(@NonNull Intent intent) {
IBinder binder = initSynchronizer();
new Thread(
() -> onHandleWork(intent)
).start();
return binder;
}
そのため、別のスレッドで「onHandleWork」を開始します。この方法を使用できます:
「bindService(.....、JobIntentService.BIND_AUTO_CREATE);」
サービスにバインドし、バインダーを返します。とにかく、サービスからバインドを解除すると、サービスは強制終了されます。サービスが強制終了されても、「onHandleWork」が実行されているスレッドがまだ停止しているので、再度バインドできません。
したがって、このバージョンを使用するのは、アクティビティが生きるまでアクティビティと通信する必要があるタスクを実行する必要がある場合のみで、アクティビティが強制終了された場合に引き続き動作する必要がある場合にのみお勧めします(再びjobServiceをバインドする可能性はありませんが、新しいものを開始...)
バインド解除後にサービスを強制終了しないようにするには、「onDestroy」の「stopForeground」の「foreground」でサービスを開始する必要があります。この方法では、「onHandleWork」メソッドを処理しているスレッドに対してのみサービスを提供できます。
GoogleがこのすばやいLoLを解決してくれることを願っています。古い「Service」と「IntentService」をすべて新しいものに変換しましたが、...以前よりも本当に最悪に動作します!
さようなら素敵なコーディングがあります;)
Android Studioをもう一度終了して実行してみてください。その後、もう一度テストしてください。私の場合、Android Studioはv 3.3.1です。サンプルを参照してください。適切に動作するコード。
public class CustomizedIntentService extends JobIntentService
{
public static final String MY_ACTION = "action.SOME_ACTION";
private static final int MY_JOB_INTENT_SERVICE_ID = 500;
public CustomizedIntentService() {
}
// Helper Methods to start this JobIntentService.
public static void enqueueJobAction(Context context, String action) {
Intent intent = new Intent(context, CustomizedIntentService.class);
intent.setAction(MY_ACTION);
enqueueWork(context, CustomizedIntentService.class, MY_JOB_INTENT_SERVICE_ID, intent);
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
String action = intent.getAction();
// action will be "action.SOME_ACTION"
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onStopCurrentWork() {
return super.onStopCurrentWork();
}
}
//必要に応じてJobIntentServiceを開始します。
CustomizedIntentService.enqueueJobAction(context、CustomizedIntentService.MY_ACTION);
私にとっては、enqueueWorkの後もサービスを開始していましたが、そのためにエラーが発生していました。
これは面白いかもしれませんが、クラスの名前をクラスの名前からenqueueWork()で独自の名前に変更しなかったため、同様の問題が発生しました。更新を行った後、正常に動作し始めました。