Пользовательский JobIntentService onHandleWork не вызывается
Недавно я обновлял приложение, над которым работаю, чтобы обрабатывать уведомления от push-уведомлений, используя JobIntentService вместо обычного IntentService, потому что это кажется правильным способом обработки этого на устройствах до леденца, а также после публикации. Я ставлю работу в очередь так:
enqueueWork(context, MyJobServiceExtension.class, JOB_ID, work);
Это декларация манифеста:
<service android:name="com.example.MyJobServiceExtension"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true"
tools:node="replace">
Я никогда не вижу обратных вызовов в onHandleWork или каких-либо журналов ошибок в моей logcat. Кто-нибудь успешно интегрировал это, что могло бы помочь?
Обновление: я проверил это на устройстве API уровня 21, и оно работало... но, похоже, на моем устройстве Android O pixel XL его не вызывают. Есть какие-нибудь подсказки, почему?
Обновление № 2: Также я, кажется, вижу, как вызывается onCreate intentservice, но ни один из других методов жизненного цикла (включая onHandleWork). Кто-нибудь тоже сталкивался с этим?
6 ответов
У меня была такая же проблема после обновления от IntentService до JobIntentService. Убедитесь, что вы удалили этот метод из вашей старой реализации:
@Override
public IBinder onBind(Intent intent) {
return null;
}
Для меня это решило проблему, и теперь это работает как до, так и после Oreo.
У меня была такая же проблема (нормально работала на устройстве до O, никаких признаков того, что что-то происходит на O-устройстве). Сегодня я попробовал снова с тем же кодом, что и вчера, теперь он работает - единственная разница в том, что я перезагрузил устройство между ними.
Моя текущая теория состоит в том, что моя начальная установка не работала; мой текущий делает, и просто повторное развертывание нового кода не очищает нарушенное состояние от JobScheduler; перезагрузка или удаление / переустановка пакета делает.
Настройка, которая работает сейчас (перенесена из прежнего IntentService):
<service
android:name=".MyJobIntentService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"/>
и начать с
Intent intent = new Intent();
intent.putExtra(EXTRA_NAME, extraValue);
JobIntentService.enqueueWork(context, MyJobIntentService.class, FIXED_JOB_ID, intent);
Обратите внимание, что намерение не является явным намерением (т. Е. Имя компонента не установлено).
Это то, что сработало для меня,
Удалить IBind
Переопределить как предложено @agirardello
и добавил следующее
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
Понятия не имею, почему это сработало.
Если вы переопределили onCreate
метод в вашем JobIntentService
, это предотвратит вызов onHandleWork.
Я преобразовал мой Service
в JobIntentService
и только после того, как я удалил onCreate
метод это сработало.
Я столкнулся с этой проблемой, пытаясь поставить в JobIntentService
с помощью JobScheduler
, В то время как JobScheduler
имеет собственный метод enqueueWork(), он не работает с JobIntentService
, Служба запустится, но onHandleWork() никогда не вызывается.
Он начал работать снова, когда я использовал статический метод enqueueWork(), который находится на JobIntentService - например:
MyJobIntentService.enqueueWork(context, ...)
Ничего из этого не было очевидно из чтения Javadoc Android.
Я столкнулся с несколько похожей проблемой с onHandleWork
не вызывается во второй раз после миграции из Service
в JobIntentService
, Логи показывали, что enqueueWork
был назван, но onHandleWork
выполнял только первый и, казалось, застрял.
После еще нескольких копаний и регистрации я обнаружил, что разница в том, что в "застрявшем" сценарии JobIntentService#onDestroy
хотя все операции в onHandleWork
были выполнены и, казалось бы, закончены.
Оказалось, что виновник был bindService
вызов этой услуги на жизненный цикл деятельности, который препятствовал выбытию первой работы и почему-то вызывал enqueueWork
после этого условия служба зависала и никогда не выполняла onHandleWork
снова.
Итак, вот неправильный журнал событий, в котором JobIntentService
будет зависать после того, как первый вызов никогда не сработает onHandleWork
снова:
enqueueWork -> first call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
enqueueWork -> second call
enqueueWork -> third call
И вот правильный журнал событий с JobIntentService
работает правильно после удаления bindService
вызов:
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
Надеюсь, это будет полезно для кого-то.
Просто попробуйте выйти и запустить Android Studio снова. Затем проверьте снова. В моем случае версия Android Studio v 3.3.1. Посмотрите пример кода, который работает правильно.
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();
}
}
// запускаем JobIntentService по мере необходимости.
CustomizedIntentService.enqueueJobAction (context, CustomizedIntentService.MY_ACTION);
Для меня я все еще запускал сервис после enqueueWork и из-за этого выдавал ошибку.
Как это ни смешно, у меня была похожая проблема, потому что я не изменил имя класса на его собственное имя в enqueueWork(), потому что я скопировал код из одного из моих классов. После того как я сделал обновление, оно начало работать правильно.
Я наконец нашел решение этой проблемы LoL
Если вы переопределяете метод onBind и вызываете работу с помощью метода enqueueWork, вам необходимо вернуть привязку к движку работы, выполняющему это:
@Override @Nullable
public IBinder onBind(@NonNull Intent intent) {
[... Do What You Want ... ]
return super.onBind(intent);
}
Возвращаем IBinder метода super.onBind, поэтому вы должны использовать его для привязки к JobIntentService.
Если вы хотите связать и вернуть другое связующее, вы можете сделать это:
@Override @Nullable
public IBinder onBind(@NonNull Intent intent) {
IBinder binder = initSynchronizer();
new Thread(
() -> onHandleWork(intent)
).start();
return binder;
}
Итак, запустив вас "onHandleWork" в другой теме. Таким образом, вы можете использовать:
"bindService (....., JobIntentService.BIND_AUTO_CREATE);"
связать с услугой и вернуть свой Binder. В любом случае, когда вы отсоединяетесь от службы, служба будет убита, и если она все еще будет работать, вы не сможете снова связать ее, потому что служба была убита, но поток, в котором все еще работает "onHandleWork"...
Поэтому я предлагаю вам использовать эту версию только в том случае, если вам нужно выполнить задачу, которая должна взаимодействовать с активностью до тех пор, пока она не станет активной, и должна работать до сих пор, если активность будет уничтожена (без возможности снова связать jobService, но только для начать новый...)
Чтобы не убить сервис после отмены привязки, вам нужно запустить его на "переднем плане" в "stopForeground" в "onDestroy". Таким образом, вы обслуживаете все еще живым только для потока, который обрабатывает методы "onHandleWork".
Я надеюсь, что Google's решит эту чертову быструю LoL, я преобразовал все старые "Service" и "IntentService" в новые рабочие места, но... они работают действительно хуже, чем раньше!
Пока, приятного кодирования;)
Я думаю, что у меня такая проблема, так как я пытаюсь поджарить какой-то текст внутри onHandleWork()
но на самом деле проблема была в том, что это было неправильно. Я должен использоватьHandler
. Это может быть проблемой, если использовать, например,AsyncTask
подклассы для выполнения в другом потоке внутри onHandleWork()
что очень плохая идея.
Для всех, кто не смог решить проблему другими ответами:
Попробуйте использовать разные JOB_ID при каждом вызове enqueueWork. Если предыдущее задание не было завершено, служба может просто зависнуть (аналогично проблеме, описанной пользователем "git pull origin"), и новое задание с другим идентификатором может решить эту проблему.