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?
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.
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).
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.
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.
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.
Ein ähnliches Problem ist aufgetreten, als onHandleWork
nach der Migration von Service
zu JobIntentService
nicht zum zweiten Mal aufgerufen wurde. In Protokollen wurde angezeigt, dass enqueueWork
aufgerufen wurde, onHandleWork
jedoch 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 onHandleWork
ausgeführt und scheinbar abgeschlossen wurden.
Es stellte sich heraus, dass der Schuldige bindService
der Aufruf dieses Dienstes zum Aktivitätslebenszyklus war, der das Entsorgen des ersten Jobs verhinderte, und aus irgendeinem Grund enqueueWork
aufrief, nachdem dieser Zustand dazu führte, dass der Dienst "hängen blieb" und nie wieder einen der folgenden onHandleWork
namen__ ausführte.
Hier ist also ein falsches Protokoll von Ereignissen, in denen JobIntentService
nach dem ersten Aufruf festzustecken scheint, der onHandleWork
nie 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 JobIntentService
nach dem Entfernen des bindService
name__-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.
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;)
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);
Für mich habe ich den Dienst nach enqueueWork noch gestartet und habe mir deshalb einen Fehler gemacht.
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.