У меня есть рабочий поток, управляемый моей активностью. При выходе из действия (например, onPause()) я отправляю сообщение в этот поток, и оно должно завершиться вскоре (миллисекунды), если что-то не пойдет не так. Обычно я бы использовал join() в onPause(), но в этом случае этот поток должен использовать поток пользовательского интерфейса, чтобы выполнить свою последовательность выключения (закрытие файлового дескриптора Accessory не работает из любого другого потока, кажется) . Таким образом, попытка заблокировать поток пользовательского интерфейса приведет к взаимоблокировке. Я ищу решение, которое каким-то образом отложит выход приложения до завершения потока. Возможно, если бы я мог просто прервать выход в таком случае, я мог бы позже вызвать finish() вручную, но я не уверен, можно ли это (прерывание) сделать.
Просто предполагать, что поток в конце концов закончит свою очистку и выйти, кажется очень небезопасной практикой.
Ответ 1 · рейтинг 1 · Alok Kulkarni
Как вы сказали, вы не можете держать поток пользовательского интерфейса в ожидании остановки фонового потока на неопределенный срок.
Вы можете сделать следующее.
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(). Если вы не уверены, что очистка может зависнуть, вам нужно перепроверить код и, если требуется, прервать поток после тайм-аута.
Ответ 2 · elijah
объявить обработчик в потоке пользовательского интерфейса. Когда другой поток завершится, отправьте (пустое) сообщение из другого потока этому обработчику, что приведет к выполнению метода handleMessage в потоке пользовательского интерфейса. Сделайте окончательную очистку пользовательского интерфейса в handleMessage.