Есть задача: запускать поток(Thread1) 1 раз и только. При этом, другой поток(Thread2) периодически создает нужный поток(Thread1). Из за невозможности контролировать количество, происходит повторение действий. Как решить красиво и правильно я не знаю.
Главный вопрос. Имеем
static Thread myThread;
@Override
public void run() {
if (myThread != null) {
if (isAlive()) {
// Если поток есть, и живой, то return.
// Т.е. получается поток создался,
// но не делая ничего завершился,
// а предыдущий, который еще работает.... дорабатывает.
return;
}
}
// Если не было return, то поток работает
}
Но, я переживаю что произойдет следующее: в потоке код выполняется в while(true) {}, т.е. постоянно. На android. И если из за нехватки памяти или другим причинам ОС она прибьет мой поток(Thread1), то другой поток(Thread2) создает его заново. Происходит код выше, и если static Thread myThread не обнулится, то получится что и не работает нужный поток и другие не смогут начать работу. Метода onDestroy нет не у Thread, не у Runnable интерфейса.
Возможно я предложил очень "некрасивое" решение и делается это совсем не так, если кто знает, подскажите в каком направлении смотреть. Я не совсем понимаю природу работы сборщика мусора в java, и политики работы ОС Android(причины завершить процесс аварийно и т.д.).
P.S. Вопрос вкратце: должен жить 1 поток либо ни одного. Если ни одного нет, иметь возможность запустить 1.
UDP: Такой код вроде работает, не знаю как будет вести себя в нестандартных ситуациях.
public static Thread myThread;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (myThread == null) {
myThread = new Thread(new TaskExecutor(this));
myThread.start();
} else {
if (!myThread.isAlive()) {
myThread = new Thread(new TaskExecutor(this));
myThread.start();
}
}
return START_STICKY;
}
Первый вариант что я писал, там почему то не срабатывает this.isAlive() внутри потока уже. Возвращает false;
UPD 2:
Eugene Krivenja ответ хороший. Но Создавая поток при пересоздании сервиса получается так: Старый сервис создан, создал поток. Потом Сервис умирает (я его сам прибил), но поток функционирует. Сервис пере создается, создает поток - имеем 2 рабочих потока, которые дублируют действия. Статик переменная решила мою проблему, но как ты сказал могут быть необъяснимые действия. Буду думать дальше, как сделать 100% безопасно.
Ответ
Хранить что-либо в статических переменных на Андроид очень не рекомендуется. Могут происходить труднообьяснимые вещи. Все из-за механизма выгрузки-загрузки классов.
Стандартный подход в вашем случае, создать потомка от класса Application и в нем хранить ссылку (не статическую) на поток, а сам поток создавать в onCreate()
В этом случае поток система уничтожит вместе с обьектом Application, а при перезапуске приложения Application создается самым первым, соответсвенно и поток будет создан.
Второй вариант с сервисом рабочий, и наверное предпочтительный, только myThread опять же не должен быть статическим и поток уничтожится только вместе с сервисом. Поэтому не стоить перезапускать поток кем-то извне, надо перезапускать сам сервис.
Как-то так. На Андроид кроме констант в статических переменных лучше ничего вообще не иметь.
Комментариев нет:
Отправить комментарий