Как отменить Сервис / IntentService / AsyncTask / Looper - PullRequest
1 голос
/ 09 сентября 2011

Я схожу с ума здесь.Я хочу простую вещь - у меня длинная задача (получение нескольких объектов данных из Интернета), и я хочу иметь возможность отменить ее.Я много чего перепробовал (много) и ничего не работает

Поток идет так:

  1. пользователь нажимает на кнопку

  2. Я начинаю работу (я пробовал с AsyncTask, Service, IntentService и Looper)

  3. задача позаботится обо всем, включая добавление текущихуведомление о ходе обновления

  4. у намерения в уведомлении есть вызов для нового действия, единственной целью которого является отмена текущей задачи

  5. в cancelActivity я пытался вызвать stopService() для Service / IntentService или сделать Looper.quit() для Looper (я не помню, что я пробовал для AsyncTask, не уверен, есть ли такой API для его отмены)

На мой взгляд, наилучшим вариантом будет использование IntentService (у меня может быть несколько задач в очереди, и IntetService будет делать это в порядке, как я хочу), но я открыт для предложений для любого типареализации - мне все равно, какой будет код, просто у меня будет возможностьo отменить задание

Заранее благодарю за помощь

Дрор

(я ухожу спать - 8 часов на одну и ту же проблему - слишком много)

Ответы [ 2 ]

1 голос
/ 09 сентября 2011

Не имеет значения, какую конкретную операцию вы используете для остановки задачи, если вы не распознаете условие остановки в фоновой логике.Единственный способ добиться этого - это если фоновый работник останавливается и уходит добросовестно.

Существует несколько возможных сценариев и решений, которые можно использовать для отмены фоновой работы.поток выполняет много коротких шагов (например, вычисление с некоторыми циклами).В этом случае проверьте какой-либо флаг (может быть isInterrupted()) между операциями и выйдите, если этот флаг указывает, что операция должна быть остановлена.

Фоновый поток ожидает на мониторе.Вызвать interrupt() в фоновом потоке, перехватить исключение в обработчике исключений, сделать соответствующие шаги, чтобы завершить эту задачу и выйти. Фоновый поток ожидает ввода-вывода.Этот вариант использования очень трудно решить в общем случае.Если вы используете какой-либо сокет, вы можете попробовать закрыть этот сокет снаружи и поймать исключение.В худшем случае вы можете просто оставить поток в состоянии, что, если он когда-либо вернется из IO, он знает, что он отменен, и результаты IO должны быть отброшены.Если вы будете делать это часто - у вас не хватит памяти, поэтому я бы не стал этого рекомендовать.

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

0 голосов
/ 09 сентября 2011

Хорошо, мне удалось сделать что-то близкое к тому, что я хочу.

Я использую IntentService, который поставит мою задачу в очередь.каждое новое задание AsyncTask.AsyncTask начинается с отправки уведомления с pendingIntent для cancelActivity.

При нажатии на уведомление пользователь получает всплывающее окно с предупреждением об остановке задачи.Если он нажимает «да», чем я stopService() в моем IntentService.

В IntentService я добавил:

    @Override
public void onDestroy() {
    currentTask.cancel(true);
    if (mNotificationHelper != null)
        mNotificationHelper.completed();
    super.onDestroy();
    stopSelf();
}

в AsyncTask, который я добавил:

    @Override
protected void onCancelled() {
    isCanclled = true;
    httpClient.getConnectionManager().shutdown();
    mNotificationHelper.completed();
    if (mAsyncTaskListener != null)
        mAsyncTaskListener.AsyncTaskCanceled();
}

так что будет сброшено все соединение, находящееся в данный момент в движении.В реальном коде, который выполняет эту работу, мне нужно поймать исключение для завершения соединения и обработать его

, так что в конце я фактически не останавливаю AsyncTask / Service, а скорее выставляю httpClient, поэтому я будубыть в состоянии отбросить соединение в асинхронном режиме, почему.

Я думаю, что это немного некрасиво, но у меня нет другого пути

спасибо всем

...