2013-07-30 6 views
7

У меня есть HandlerThread, на который я продолжаю публиковать запуск каждые 5 секунд. Что-то вроде этого:Как быстро выйти из петлителя HandlerThread

HandlerThread thread = new HandlerThread("MyThread"); 
thread.start(); 
Handler handler = new Handler(thread.getLooper()); 
handler.post(new Runnable() { 
    public void run() { 
    //... 
    handler.postDelayed(this, 5000); 
    } 
}); 

мне нужно бросить петлитель в какой-то момент, через 60 секунд или что-то подобное .. поэтому я пишу:

mainHandler = new Handler(Looper.myLooper()); //main thread's 
mainHandler.postDelayed(new Runnable() { 
    @Override 
    public void run() { 
    thread.getLooper().quit(); 
    } 
}, 60000); 

Я думаю, что это приводит к тому, петлитель бросить курить резко , так что я начинаю получать это "предупреждение" сообщения:

W/MessageQueue (3726): java.lang.RuntimeException: Обработчик (android.os.Handler) {4823dbf8} отправка сообщения в обработчике на мертвое нить

Я хочу, чтобы избежать этой ошибки Сообща, я не думал, что я мог бы решить эту проблему с помощью метода Looper.quitSafely() .. но я проверил API и это больше не доступно. Кто-нибудь знает, что с ним случилось? (Это не устарел, как некоторые другие методы).

Есть ли способ, чтобы я мог безопасно покинуть петлитель? Благодаря!

+0

остановка отправки handler.postDelayed (это, 5000) с задержкой Runnables – pskink

+0

как с помощью флага или что-то? – sundie

+0

Возможно, вы могли бы попробовать thread.getLooper(). QuitSafely()? – Richard

ответ

0

Im не Thread Гуру, но этот способ может дать вам направление:

... 
_thread.setRunning(true); 
_thread.start(); 

.. 

public void stopThread(){ 
    boolean retry = true; 
    _thread.setRunning(false); 
    while (retry) { 
     try { 
      _thread.join(); 
      retry = false; 
      Log.e("test", "thread stopped"); 
     } catch (InterruptedException e) { 
      Log.e("test", "can't stop thread, retrying..."); 
      // we will try it again and again... 
     } 
    } 
} 

В вашей теме:

while (isRunning) { 
    //... 
} 

первым все вы реализуете run метод в цикле (while(isRunnig){}).

На конце вы переключаете флаг на false и «ждите» для join.

1

Вы можете попытаться использовать логическое значение, чтобы узнать, должен ли выполняться код. Что-то вроде этого:

private boolean runHandler = true; 

... 

HandlerThread thread = new HandlerThread("MyThread"); 
thread.start(); 
Handler handler = new Handler(thread.getLooper()); 
handler.post(new Runnable() { 
    public void run() { 
     if(runHandler){ 
      //... 
      handler.postDelayed(this, 5000); 
     } 
    }  
}); 

mainHandler = new Handler(Looper.myLooper()); //main thread's 
mainHandler.postDelayed(new Runnable() { 
    @Override 
    public void run() { 
     runHandler = false; 
    } 
}, 60000); 
+0

спасибо, это просто обходное решение :) – sundie

+0

что делать, если у меня много обработчиков? Я имею в виду, что я бы не хотел сохранять один логический для каждого потока ...: P – sundie

+0

Да, в этом случае вам следует искать способ остановить обработчик. Я думаю, Handler-> removeCallbacks будет работать, если сообщение находится в очереди, но если обработчик выполняется, я не уверен, что это остановит выполнение. –