Как заставить остановить Intent Service в процессе?

У меня есть намеренная служба, которая загружает несколько гигабайт видео. У меня есть кнопка "Стоп", чтобы остановить загрузку, если случайно нажать "Пуск" или что-то еще. Я знаю, что это было задано пару раз, но без рабочего ответа для меня.

Я пытаюсь вызвать stopService(), не работает. Это просто вызывает IntentService.OnDestroy(). Я попытался вызвать stopSelf() внутри onDestroy, также не работает.

Я пытался иметь что-то вроде флага, но onHandleIntent не вызывается, если он уже запущен, он ожидает завершения текущей работы и выполнения. И даже если бы это сработало, мне нужно было бы что-то вроде гигантского if-заявления, что отстой

Является ли мой единственный способ переписать его на обычную службу?

//ответа

public class SyncService extends IntentService {

    boolean isCanceled;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent.hasExtra("action")) {

            // Set the canceling flag
            isCanceled= intent.getStringExtra("action").equals("cancel");

        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        // Clean up the possible queue
        if (intent.hasExtra ("action")) {
            boolean cancel = intent.getStringExtra ("action"). Equals ("cancel");
            if (cancel) {
                return;
            }
        }

        ...

        Get your inputStream from HttpUrlConnection or whatever

        ...

        while ((bytesRead = in.read(buffer)) > 0) {
            if (isCanceled) {
                isCanceled = false;
                break;
            }

            ...
        }

    }
}

И запустите его с помощью

Intent intent = new Intent(context, SyncService.class);
intent.putExtra("action", "cancel");
context.startService(intent);

Ответ 1

У вас есть две отдельные проблемы, я бы подумал:

  • Как остановить текущую загрузку

  • Как остановить загруженные в очередь загрузки, которые должны выполняться после завершения текущей версии

Первый должен быть "чем-то вроде флага", который вы проверяете при загрузке данных. В противном случае ничто не остановит вашу операцию загрузки. Если вы используете типичный рецепт HttpUrlConnection, вы проверяете этот флаг в своем цикле, где вы читаете HTTP InputStream, и пишите в FileOutputStream. Вы устанавливаете этот флаг через вызов startService() с определенной структурой Intent, идентифицируя его как операцию "отменить". Вам нужно переопределить onStartCommand() в IntentService, посмотреть на Intent, использовать его, чтобы установить флаг, если это отменить Intent, или цепочку для суперкласса для любого другого типа Intent.

Если у вас также могут быть другие команды в очереди (сценарий №2), вам нужно будет также проверить этот флаг в верхней части onHandleIntent().

Ответ 2

Учитывая, что вы не разместили информацию о том, как вы правильно обрабатываете видеозапись, это может не сработать (внутри onHandleIntent будет выполняться какой-то цикл, в котором выполняются загрузки). Вы можете использовать переменную статического класса внутри IntentService, которая содержит состояние Stop/Start загрузки, так что его можно установить с помощью Activity. Затем внутри onHandleIntent вам придется регулярно проверять состояние, чтобы он знал, когда отменить операции.