webentwicklung-frage-antwort-db.com.de

Benutzerdefinierter JobIntentService onHandleWork wird nicht aufgerufen

Ich habe vor kurzem eine App aktualisiert, an der ich arbeite, um Benachrichtigungen von Push zu verarbeiten, wobei ein JobIntentService anstelle eines normalen IntentService verwendet wird, da dies als der richtige Weg erscheint, dies auf Pre-Lollipop-Geräten sowie auf Post zu tun. Ich beziehe die Arbeit als solche ein:

enqueueWork(context, MyJobServiceExtension.class, JOB_ID, work);

Dies ist die Manifesterklärung:

<service Android:name="com.example.MyJobServiceExtension" Android:permission="Android.permission.BIND_JOB_SERVICE" Android:exported="true" tools:node="replace">

Ich sehe niemals Rückrufe in onHandleWork oder Fehlerprotokolle in meinem Logcat. Hat jemand dies erfolgreich integriert, könnte das helfen?

Update: Ich habe dies auf einem API-Gerät der Stufe 21 getestet und es hat funktioniert .. aber es scheint nicht, dass es auf meinem Android O Pixel XL-Gerät angerufen wird. Gibt es Hinweise, warum?

Update Nr. 2: Ich sehe auch, dass der onCreate von intentservice aufgerufen wird, aber keine der anderen Lebenszyklusmethoden (einschließlich onHandleWork). Hat jemand das auch gesehen?

22
Eshaan

Das gleiche Problem hatte ich nach dem Upgrade von IntentService auf JobIntentService. Stellen Sie sicher, dass Sie diese Methode aus Ihrer alten Implementierung entfernen:

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

Für mich wurde das Problem gelöst, und jetzt funktioniert es sowohl vor als auch nach Oreo.

48
agirardello

Ich hatte das gleiche Problem (funktionierte gut mit einem Pre-O-Gerät, kein Hinweis darauf, dass irgendetwas auf einem O-Gerät passiert). Heute habe ich es noch einmal mit genau demselben Code wie gestern versucht, jetzt funktioniert es - der Unterschied besteht nur darin, dass ich das Gerät zwischendurch neu gestartet habe.

Meine derzeitige Theorie besagt, dass mein anfängliches Setup nicht funktioniert hat. Mein aktueller Code wird durch das erneute Implementieren von neuem Code nicht aus dem JobScheduler entfernt. Ein Neustart oder eine Deinstallation/Neuinstallation des Pakets ist erforderlich.

Das jetzt funktionierende Setup (migriert von einem früheren IntentService):

<service
    Android:name=".MyJobIntentService"
    Android:exported="false"
    Android:permission="Android.permission.BIND_JOB_SERVICE"/>

und beginne mit 

Intent intent = new Intent(); 
intent.putExtra(EXTRA_NAME, extraValue);
JobIntentService.enqueueWork(context, MyJobIntentService.class, FIXED_JOB_ID, intent);

Beachten Sie, dass die Absicht nicht eine explizite Absicht ist (d. H. Der Komponentenname ist nicht festgelegt).

6
Jule

Ich bin auf dieses Problem gestoßen, als ich versucht habe, das JobIntentService mit JobScheduler in die Warteschlange zu stellen. JobScheduler verfügt zwar über eine eigene enqueueWork () -Methode, funktioniert jedoch nicht mit JobIntentService. Der Dienst wird gestartet, aber onHandleWork () wird nie aufgerufen.

Es hat wieder funktioniert, als ich die statische enqueueWork () -Methode im JobIntentService verwendet habe - zB:

MyJobIntentService.enqueueWork(context, ...)

Nichts davon wurde beim Lesen von Android's Javadoc offensichtlich.

2
KATHYxx

Wenn Sie die onCreate-Methode in Ihrer JobIntentService überschrieben haben, wird der Aufruf von onHandleWork verhindert.

Ich habe meine Service in JobIntentService konvertiert und erst nachdem ich die onCreate-Methode entfernt hatte, hat sie funktioniert.

2

Das hat bei mir funktioniert,

Entfernen Sie die IBind-Überschreibung, wie von @agirardello vorgeschlagen

und fügte folgendes hinzu

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

Habe keine Ahnung, warum das funktioniert hat.

2
Sanket Berde

Ein ähnliches Problem ist aufgetreten, als onHandleWorknach der Migration von Servicezu JobIntentServicenicht zum zweiten Mal aufgerufen wurde. In Protokollen wurde angezeigt, dass enqueueWorkaufgerufen wurde, onHandleWorkjedoch nur den ersten ausführte und festzustecken schien.

Nach einigem weiteren Graben und Aufzeichnen stellte ich fest, dass der Unterschied darin bestand, dass in einem "festgefahrenen" Szenario JobIntentService#onDestroy vorhanden war, obwohl alle Vorgänge in onHandleWorkausgeführt und scheinbar abgeschlossen wurden.

Es stellte sich heraus, dass der Schuldige bindServiceder Aufruf dieses Dienstes zum Aktivitätslebenszyklus war, der das Entsorgen des ersten Jobs verhinderte, und aus irgendeinem Grund enqueueWorkaufrief, nachdem dieser Zustand dazu führte, dass der Dienst "hängen blieb" und nie wieder einen der folgenden onHandleWorknamen__ ausführte.

Hier ist also ein falsches Protokoll von Ereignissen, in denen JobIntentServicenach dem ersten Aufruf festzustecken scheint, der onHandleWorknie wieder auslöst:

enqueueWork -> first call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
enqueueWork -> second call
enqueueWork -> third call

Und hier ist das korrekte Ereignisprotokoll, bei dem JobIntentServicenach dem Entfernen des bindServicename__-Aufrufs ordnungsgemäß funktioniert:

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

Hoffe das wird jemandem weiterhelfen.

1
git pull origin

Für alle, die das Problem mit den anderen Antworten nicht lösen konnten:

Versuchen Sie, bei jedem Aufruf von enqueueWork unterschiedliche JOB_IDs zu verwenden. Wenn ein vorheriger Job nicht beendet wurde, steckt der Service möglicherweise nur fest (ähnlich dem Problem, das der Benutzer "git pull Origin" beschrieben hat), und ein neuer Job mit einer anderen ID kann dieses Problem beheben.

Endlich habe ich die Lösung für dieses LoL-Problem gefunden

Wenn Sie die "onBind" -Methode überschreiben und die Arbeit mit der "enqueueWork" -Methode aufrufen, müssen Sie die Bindung an die Engine der Arbeit zurückgeben, die dies ausführt:

@Override @Nullable
    public IBinder onBind(@NonNull Intent intent) {
        [... Do What You Want ... ]
        return super.onBind(intent);
    }

Gibt also den IBinder der "super.onBind" -Methode zurück, so müssen Sie diesen zum Binden an den JobIntentService verwenden.

Wenn Sie einen anderen Binder binden und zurückgeben möchten, können Sie dies tun:

@Override @Nullable
    public IBinder onBind(@NonNull Intent intent) {
        IBinder binder = initSynchronizer();
        new Thread(
                () -> onHandleWork(intent)
            ).start();
        return binder;
    }

Also indem du "onHandleWork" in einem anderen Thread startest. Auf diese Weise können Sie Folgendes verwenden:

"bindService (....., JobIntentService.BIND_AUTO_CREATE);"

an den Dienst zu binden und Ihre Sammelmappe zurückzugeben. Auf jeden Fall wird der Dienst beendet, wenn Sie die Bindung zum Dienst aufheben. Wenn er weiterhin ausgeführt wird, können Sie ihn nicht erneut binden, da der Dienst beendet wurde, aber der Thread, in dem "onHandleWork" noch ausgeführt wird.

Daher empfehle ich Ihnen, diese Version nur zu verwenden, wenn Sie eine Aufgabe ausführen müssen, die mit der Aktivität kommunizieren muss, bis sie lebendig ist, und wenn die Aktivität beendet wird, weiterarbeiten müssen (ohne die Möglichkeit, den jobService erneut zu binden, sondern nur an fange einen neuen an ...)

Um den Dienst nach dem Aufheben der Bindung nicht zu beenden, müssen Sie ihn im "Vordergrund" und im "OnDestroy" im "StopForeground" starten. Auf diese Weise bleiben Sie nur für den Thread am Leben, der die "onHandleWork" -Methoden verarbeitet.

Ich hoffe, Google löst dieses Problem schnell, ich habe alle älteren "Service" und "IntentService" auf die neuen Jobs umgestellt, aber ... sie funktionieren wirklich am schlechtesten als zuvor!

Tschüss, hab eine nette Codierung;)

0
Z3R0

Versuchen Sie einfach, das Android Studio erneut zu beenden und auszuführen. Dann erneut testen ... In meinem Fall ist die Version von Android Studio Version 3.3.1 .. Siehe den Beispielcode, der ordnungsgemäß funktioniert.

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

// Starten Sie den JobIntentService nach Bedarf.

CustomizedIntentService.enqueueJobAction (Kontext, CustomizedIntentService.MY_ACTION);

0
Jay

Für mich habe ich den Dienst nach enqueueWork noch gestartet und habe mir deshalb einen Fehler gemacht.

0
Tarun Goel

So lustig das auch klingen mag, ich hatte ein ähnliches Problem, weil ich den Namen der Klasse in enqueueWork () nicht in einen eigenen Namen geändert habe, weil ich den Code aus einer meiner Klassen kopiert habe. Nachdem ich das Update gemacht habe, hat es richtig funktioniert.

0
leeCoder