Блокировка выхода из активности Android до завершения очистки

У меня есть рабочий поток, управляемый моей активностью. При выходе из действия (например, onPause()) я отправляю сообщение в этот поток, и оно должно завершиться вскоре (миллисекунды), если что-то не пойдет не так. Обычно я бы использовал join() в onPause(), но в этом случае этот поток должен использовать поток пользовательского интерфейса, чтобы выполнить свою последовательность выключения (закрытие файлового дескриптора Accessory не работает из любого другого потока, кажется) . Таким образом, попытка заблокировать поток пользовательского интерфейса приведет к взаимоблокировке. Я ищу решение, которое каким-то образом отложит выход приложения до завершения потока. Возможно, если бы я мог просто прервать выход в таком случае, я мог бы позже вызвать finish() вручную, но я не уверен, можно ли это (прерывание) сделать.

Просто предполагать, что поток в конце концов закончит свою очистку и выйти, кажется очень небезопасной практикой.


person Ytai    schedule 03.01.2012    source источник


Ответы (2)


Как вы сказали, вы не можете держать поток пользовательского интерфейса в ожидании остановки фонового потока на неопределенный срок.

Вы можете сделать следующее.

1) Прервите поток в onPause(). (Это не сохранит никакой информации, если вы хотите во время очистки)

2) Если вы хотите сохранить некоторую информацию и выполнить чистый выход, вы можете запустить службу Android в onPause() и выполнить там очистку. (Своевременно проверяйте наличие логического флага в потоке) пример: псевдопример

void run(){
while(true){
   if(bExit){
    doCleanupWork();
   }
  //Do work
  doWork();

  }
}

void doCleanupWork(){
startCleanupService();
}

void onPause(){
bExit = true;
}

Правки

3) Переопределите onBackPressed() класса Activity, чтобы он не выходил напрямую. Запустите AsyncTask и покажите пользователю диалоговое окно, указывающее на обработку, в то время как вызовы очистки происходят в doInBackground(). Если вы не уверены, что очистка может зависнуть, вам нужно перепроверить код и, если требуется, прервать поток после тайм-аута.

person Alok Kulkarni    schedule 04.01.2012
comment
Выполнение очистки после выхода из приложения не является проблемой. Проблема заключается в откладывании выхода приложения до завершения очистки. - person Ytai; 04.01.2012
comment
Относительно (3): onBackPressed() — не единственная ситуация, когда приложение закрывается. Любая попытка охватить все возможные пути выхода, если это вообще возможно, очень ненадежна, непереносима и не рассчитана на будущее. Что касается AsyncTask, то это совершенно необязательно. Обычно очистка занимает миллисекунды. Я просто хочу поймать любой шанс, что он зависнет, и убедиться, что приложение не перезапустится, прежде чем полностью очистить предыдущий запуск. - person Ytai; 05.01.2012

объявить обработчик в потоке пользовательского интерфейса. Когда другой поток завершится, отправьте (пустое) сообщение из другого потока этому обработчику, что приведет к выполнению метода handleMessage в потоке пользовательского интерфейса. Сделайте окончательную очистку пользовательского интерфейса в handleMessage.

person elijah    schedule 04.01.2012
comment
Но это произойдет после того, как сообщения onPause() или onStop() уже обработаны, то есть приложение уже завершило работу, не так ли? Чего я пытаюсь добиться, так это отложить выход приложения до тех пор, пока не завершится поток, но без блокировки потока пользовательского интерфейса на join() (поскольку часть очистки потока включает выполнение работы над потоком пользовательского интерфейса, и это вызовет взаимоблокировку) . - person Ytai; 04.01.2012
comment
хмммм -- я бы чувствовал себя комфортно, просто сообщив потоку о завершении работы из onStop... Я не думаю, что есть какой-либо способ прервать завершение работы, так что все, что вы можете сделать, это сообщить потоку, чтобы он прошел через процедуру завершения работы. Вы обеспокоены тем, что поток может не очиститься полностью? Ему должно быть предоставлено время, чтобы сделать то, что ему нужно (т. е. рабочий поток не будет уничтожен сразу после завершения потока пользовательского интерфейса). - person elijah; 04.01.2012
comment
Меня беспокоят проблемы с очисткой. Я предпочитаю получить ANR, чем застрявший поток... Кроме того, я хочу убедиться, что приложение не будет перезапущено перед чистым выходом. Есть много ситуаций, когда приложение будет остановлено/немедленно перезапущено, что может вызвать проблемы. - person Ytai; 05.01.2012