web-dev-qa-db-ja.com

カスタムJobIntentService onHandleWorkは呼び出されません

最近、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を含む)はありません。誰もこれに遭遇しましたか?

26
Eshaan

IntentServiceからJobIntentServiceにアップグレードした後、同じ問題が発生しました。古い実装からこのメソッドを削除してください:

@Override
public IBinder onBind(Intent intent) {
    return null;
}

私にとってこれで問題は解決しましたが、今ではオレオの前後で動作します。

56
agirardello

私は同じ問題を抱えていました(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は設定されていません)。

8
Jule

JobIntentServiceを使用してJobSchedulerをエンキューしようとすると、この問題に遭遇しました。 JobSchedulerには独自のenqueueWork()メソッドがありますが、JobIntentServiceでは機能しません。サービスは開始されますが、onHandleWork()は呼び出されません。

JobIntentServiceにある静的enqueueWork()メソッドを使用すると、再び機能し始めました-例:

MyJobIntentService.enqueueWork(context, ...)

これは、Androidのjavadocを読んでも明らかではありませんでした。

2
KATHYxx

onCreateJobIntentServiceメソッドをオーバーライドした場合、onHandleWorkが呼び出されなくなります。

ServiceJobIntentServiceに変換しましたが、onCreateメソッドを削除して初めて機能しました。

2

これは私のために働いたものです、

@agirardelloが示唆するIBindオーバーライドを削除します

以下を追加しました

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

これがなぜ機能したのか分かりません。

2
Sanket Berde

onHandleWorkからServiceに移行した後、2回目にJobIntentServiceが呼び出されないという同様の問題に遭遇しました。ログには、enqueueWorkが呼び出されたが、onHandleWorkが最初のみを実行し、スタックしているように見えたことが示されていました。

さらに掘り進んでログを記録したところ、「スタック」シナリオではJobIntentService#onDestroyonHandleWorkのすべての操作が実行され、一見終了したように見えますが。

原因は、最初のジョブの破棄を妨げていたアクティビティライフサイクルへのそのサービスの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

これが誰かに役立つことを願っています。

1
git pull origin

他の回答で問題を解決できなかったすべての人に:

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」をすべて新しいものに変換しましたが、...以前よりも本当に最悪に動作します!

さようなら素敵なコーディングがあります;)

0
Z3R0

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);

0
Jay

私にとっては、enqueueWorkの後もサービスを開始していましたが、そのためにエラーが発生していました。

0
Tarun Goel

これは面白いかもしれませんが、クラスの名前をクラスの名前からenqueueWork()で独自の名前に変更しなかったため、同様の問題が発生しました。更新を行った後、正常に動作し始めました。

0
leeCoder