Я не видел примера использования jobFinshed из JobService, похоже, мы должны отслеживать изменения, когда выполняется какое-то условие, мы должны вызывать метод jobFinished()
, я прав?
Android: как использовать JobFinished из JobService
Ответы (4)
Сложность вызова jobFinished()
из другого класса, такого как IntentService
, похоже, заключается в получении экземпляра вашего класса, который расширяет JobService
для использования для вызова jobFinished()
. Вы можете получить информацию о запланированной работе, но не о JobService
(по крайней мере, я не могу найти способ). Я могу придумать 3 способа вызова jobFinished()
.
Если вам все равно, успешна ваша работа или нет, или если ваша работа занимает очень мало времени.
В одном из моих JobService
классов я выполняю периодическую работу. Я не беспокоюсь о том, как справляться с неудачами. Задача будет выполнена снова достаточно скоро. Если это так, вы можете сделать это.
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;
}
Это также то, как вы хотите сделать это, если ваша работа достаточно коротка, это не проблема сделать это в потоке пользовательского интерфейса. В этом случае выполните всю свою работу в onStartJob()
, а затем верните false.
Используйте BroadcastReceiver для отправки сообщения из IntentService в JobService (отдельный файл для каждого класса).
// common Strings
public static final String IS_SUCCESS = "isSuccess";
public static final String MY_BC_RCVR = "MyBroadcastRcvr";
Ваш 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);
}
};
}
и ваш 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);
}
}
Вложите класс рабочего потока в класс JobService.
Я привел пример AsyncTask
на основе этого Пост на среднем уровне (на который также ссылается Арсений Левин) от Google Developer Advocate, но также должна быть возможность использовать IntentService
(см. этот SO post для вложения 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);
}
}
}
}
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver)
в методе onStopJob
и методе BroadcastReceiver::onReceive
?
- person Jsyntax; 06.09.2018
startService
(2-й подход) в JobService, и когда мое приложение перешло в фоновый режим, задание не смогло запустить службу (IllegalStateException). запустить новую фоновую службу и т. д.), но, по-видимому, вы не можете. В итоге я начал JobIntentService
с JobService
. На данный момент JobService
является избыточным, но я хотел сохранить проверку ограничений, предусмотренную планировщиком заданий.
- person Jsyntax; 06.09.2018
Если ваш метод onStartJob()
возвращает true
, это означает, что вы выполняете работу в фоновом режиме в поддержку этой работы. Этот фоновый поток должен вызвать jobFinished()
, когда эта работа будет завершена или если задание необходимо перепланировать.
JobService
.
- person CommonsWare; 11.01.2019
Простой подход — запустить новый поток из onStartJob, как показано ниже:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class MyJobService extends JobService {
@Override
public boolean onStartJob(final JobParameters params) {
new Thread(new Runnable() {
@Override
public void run() {
// do your job here
jobFinished(params, true);
}
}).start();
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
return true;
}
}
Как объяснил @CommonsWare, внутри onStartJob
вы решите, требуется ли дальнейшая работа в фоновом потоке. Только в этом случае вы должны вызвать jobFinished
из этого фонового потока. Просто чтобы ответить на ваш конкретный вопрос - от вашего имени не требуется отслеживание условий. JobService
позвонит onStopJob
, если заданные вами условия перестанут выполняться.
Пример jobFinished
можно найти здесь: https://medium.com/google-developers/scheduling-jobs-like-a-pro-with-jobscheduler-286ef8510129