I didn't see example of using jobFinshed of JobService, seems like we have to track changes when some condition meet we have to call jobFinished()
method, am I right?
The difficulty of calling jobFinished()
from another class like an IntentService
seems to be getting an instance of your class that extends JobService
to use to call jobFinished()
. You can get info on the scheduled job, but not on the JobService
(at least, I can't find a way). I can think of 3 ways to call jobFinished()
.
In one of my JobService
classes, I'm doing periodic work. I'm not worried about handling failures. The task will execute again soon enough. If this is the case, you can do this.
public boolean onStartJob(JobParameters params) {
startService(new Intent(this, MyIntentServiceThatDoesTheWork.class));
// job not really finished here but we assume success & prevent backoff procedures, wakelocking, etc.
jobFinished(params, false);
return true;
}
This is also the way you want to do it if your work is short enough it's no problem to do it on the UI thread. In this case, do all your work in onStartJob()
then return false.
// common Strings
public static final String IS_SUCCESS = "isSuccess";
public static final String MY_BC_RCVR = "MyBroadcastRcvr";
Your JobService
public class MyJobService extends JobService {
JobParameters mParams;
public boolean onStartJob(JobParameters params) {
mParams = params;
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter(MY_BC_RCVR));
startService(new Intent(this, MyIntentServiceThatDoesTheWork.class));
return true;
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
boolean isSuccess = false;
if(intent.hasExtra(IS_SUCCESS)) {
isSuccess = intent.getBooleanExtra(IS_SUCCESS, false);
}
LocalBroadcastManager.getInstance(context).unregisterReceiver(this);
jobFinished(mParams, !isSuccess);
}
};
}
& your IntentService
public class MyIntentServiceThatDoesTheWork extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
boolean isSuccess = methodToDoAllMyWork();
Intent bcIntent = new Intent(MY_BC_RCVR);
bcIntent.putExtra(IS_SUCCESS, isSuccess);
LocalBroadcastManager.getInstance(this).sendBroadcast(bcIntent);
}
}
I've given an example of an AsyncTask
based on this Medium post (also referenced by Arseny Levin) from a Google Developer Advocate but it should also be possible to use an IntentService
(see this SO post for nesting IntentService
).
public class MyJobService extends JobService {
JobParameters mParams;
public boolean onStartJob(JobParameters params) {
mParams = params;
new MyAsyncTaskThatDoesTheWork().execute();
return true;
}
private class MyAsyncTaskThatDoesTheWork extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
return methodToDoAllMyWork();
}
@Override
protected void onPostExecute(Boolean isSuccess) {
if(mParams != null) {
jobFinished(mParams, !isSuccess);
}
}
}
}