I recently was updating an app that I work on to handle notifications from push using a JobIntentService
instead of a regular IntentService
because
As funny as this may sound, l had a similar issue because l did not change the name of the class to its own name in the enqueueWork() because l copied the code from one of my classes. After l made the update it started working properly.
I encountered a somewhat similar problem with onHandleWork
not being called the second time after migrating from Service
to JobIntentService
. Logs were showing that enqueueWork
was called but onHandleWork
was executing only the first and appeared to be stuck.
After some more digging and logging, I discovered that the difference was that in a "stuck" scenario there was JobIntentService#onDestroy
even though all operations in onHandleWork
were performed and seemingly finished.
Turned out that the culprit was bindService
call of that service to activity lifecycle which was preventing disposing of the first job and for some reason calling enqueueWork
after this condition was causing the service to "stuck" and never run any of the following onHandleWork
again.
So, here is an incorrect log of events in which JobIntentService
will appear to be stuck after the first call never triggering onHandleWork
again:
enqueueWork -> first call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
enqueueWork -> second call
enqueueWork -> third call
And here is the correct log of events with JobIntentService
functioning correctly after removing bindService
call:
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
Hope this will be helpful to someone.
I finally found the solution for that problem LoL
If you Override the "onBind" method and u call the work using the "enqueueWork" method you need to return the bind to the engine of the work doing this:
@Override @Nullable
public IBinder onBind(@NonNull Intent intent) {
[... Do What You Want ... ]
return super.onBind(intent);
}
So returning the IBinder of the "super.onBind" method, so you must use that to bind to the JobIntentService.
If you want to bind and return another binder you can do that:
@Override @Nullable
public IBinder onBind(@NonNull Intent intent) {
IBinder binder = initSynchronizer();
new Thread(
() -> onHandleWork(intent)
).start();
return binder;
}
So by starting you "onHandleWork" in another Thread. This way you can use:
"bindService(....., JobIntentService.BIND_AUTO_CREATE);"
to bind to the service and return your Binder. Anyway when you unbind from the service the service will get killed, and if it still run you cannot bind again to it because the service got killed but the thread in which the "onHandleWork" is still running...
So I suggest you to use this version only if you have to do a task which need to communicate with the activity until it is alive and need to still working if the activity get killed (without the possibility to bind again the jobService, but only to start a new one...)
To don't kill the service after the unbind you need to start it in "foreground" the "stopForeground" in the "onDestroy". This way you service still be alive just for the thread which is handling the "onHandleWork" methods.
I hope google's will solve this sh*t fast LoL, I converted all the older "Service" and "IntentService" to the new one jobs but... they work really worst than before!
Bye have a nice coding ;)
If you have overridden the onCreate
method in your JobIntentService
, it will prevent the onHandleWork to be called.
I converted my Service
to JobIntentService
and only after I removed the onCreate
method it worked.
I had the same issue after upgrading from IntentService to JobIntentService. Make sure you remove this method from your old implementation:
@Override
public IBinder onBind(Intent intent) {
return null;
}
For me this solved the problem, and now it works both on pre- and post-Oreo.
I ran into this issue trying to enqueue the JobIntentService
using JobScheduler
. While JobScheduler
has its own enqueueWork()
method, it doesn't work with JobIntentService
. The service will start but onHandleWork()
is never called.
It started working again when I used the static enqueueWork()
method that is on the JobIntentService
- eg:
MyJobIntentService.enqueueWork(context, ...)
None of this was obvious from reading Android's javadoc.