Пользовательский JobIntentService onHandleWork не вызывается

Недавно я обновлял приложение, над которым я работаю, для обработки уведомлений с помощью JobIntentService вместо обычного IntentService, потому что это похоже на правильный способ справиться с этим на устройствах pre-lollipop, а также на post. Я запускаю работу как таковую:

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. Кто-нибудь успешно интегрировал это, что могло бы помочь?

Обновление: я тестировал это на устройстве уровня 21 api, и это сработало. Но похоже, что это не похоже на вызов моего устройства Android с пиксельным XL-устройством Android. Любые подсказки относительно того, почему?

Update # 2: Также я вижу, что вызов intentservice onCreate вызывается, но ни один из других методов жизненного цикла (в том числе onHandleWork). Кто-нибудь столкнулся с этим?

Ответ 1

У меня была такая же проблема после обновления с IntentService до JobIntentService. Убедитесь, что этот метод удален из старой версии:

@Override
public IBinder onBind(Intent intent) {
    return null;
}

Для меня это решило проблему, и теперь она работает как на пре-, так и на пост-Орео.

Ответ 2

У меня была такая же проблема (отлично работал на устройстве pre-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);

Обратите внимание, что намерение не является явным намерением (т.е. имя компонента не установлено).

Ответ 3

Я столкнулся с этой проблемой, пытаясь присвоить значение JobIntentService с помощью JobScheduler. Хотя JobScheduler имеет свой собственный метод enqueueWork(), он не работает с JobIntentService. Служба начнется, но onHandleWork() никогда не вызывается.

Он снова начал работать, когда я использовал статический метод enqueueWork(), который находится в JobIntentService - например:

MyJobIntentService.enqueueWork(context, ...)

Ничего из этого не было видно при чтении Android javadoc.

Ответ 4

Это то, что сработало для меня,

Удалите IBind Override, как предложено @agirardello

и добавил следующее

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

Не знаю, почему это сработало.

Ответ 5

Если вы переопределили метод onCreate в своем JobIntentService, это предотвратит вызов onHandleWork.

Я преобразовал свой Service в JobIntentService и только после удаления метода onCreate он onCreate.

Ответ 6

Я столкнулся с несколько похожей проблемой, когда onHandleWork не вызывали второй раз после перехода из Service в JobIntentService. Журналы показывали, что enqueueWork был вызван, но onHandleWork выполнял только первое и, похоже, onHandleWork.

После еще нескольких копаний и регистрации я обнаружил, что разница в том, что в "застрявшем" сценарии существует JobIntentService#onDestroy хотя все операции в onHandleWork были выполнены и, казалось бы, завершены.

Оказалось, что bindService был вызов bindService этого сервиса на жизненный цикл активности, который препятствовал утилизации первого задания и по какой-то причине вызывал enqueueWork после того, как это условие вызывало " enqueueWork службы и никогда больше не запускало ни одного из следующих onHandleWork.

Итак, вот неправильный журнал событий, в котором JobIntentService будет 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

Надеюсь, это будет полезно для кого-то.

Ответ 7

Для меня я все еще запускал сервис после enqueueWork и дал мне ошибку из-за этого.

Ответ 8

Просто попробуйте выйти и запустить 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);

Ответ 9

Как это ни смешно, у меня была похожая проблема, потому что я не изменил имя класса на его собственное имя в enqueueWork(), потому что я скопировал код из одного из моих классов. После того как я сделал обновление, оно начало работать правильно.

Ответ 10

Я наконец нашел решение этой проблемы 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 решит эту чертовски быстрый LoL, я преобразовал все старые "Service" и "IntentService" в новые рабочие места, но... они работают действительно хуже, чем раньше!

Пока приятного кодирования;)