2013-07-30 7 views
7

Ho un HandlerThread, a cui continuo a postare una eseguibile ogni 5 secondi. Qualcosa di simile a questo:Come chiudere il looper di HandlerThread in modo sicuro

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

ho bisogno di uscire dal crochet ad un certo punto, dopo 60 secondi o qualcosa del genere .. quindi scrivo:

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

penso che questo fa sì che il crochet di smettere bruscamente , così ho iniziare a ricevere questo "avvertimento" messaggi:

W/MessageQueue (3726): java.lang.RuntimeException: Handler (android.os.Handler) {} 4823dbf8 l'invio di un messaggio a un gestore su un morto filo

voglio evitare questo msg di errore, ho pensato che avrei potuto risolverlo utilizzando il metodo Looper.quitSafely() .. ma ho controllato il API e non è più a disposizione. Qualcuno sa cosa gli è successo? (Non è deprecato come altri metodi).

C'è un modo per uscire in sicurezza dal crochet? Grazie!

+0

interrompere l'invio di handler.postDelayed (questa, 5000) in ritardo Runnables – pskink

+0

come l'utilizzo di una bandiera o qualcosa del genere? – sundie

+0

forse potresti provare thread.getLooper(). QuitSafely()? – Richard

risposta

0

Im Non avvitare Guru, ma in questo modo può dare direzione:

... 
_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... 
     } 
    } 
} 

nel tuo thread:

while (isRunning) { 
    //... 
} 

prima tutto si implementa run metodo in loop (while(isRunnig){}).

Al termine, si cambia flag su false e si "aspetta" per join.

1

Si potrebbe provare a utilizzare un booleano per sapere se il codice deve essere eseguito. Qualcosa di simile a questo:

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

grazie, questa è una soluzione semplice :) – sundie

+0

cosa succede se ho molti molti handlerthreads? Voglio dire, non vorrei mantenere un booleano per ogni thread ...: P – sundie

+0

Sì, in tal caso dovresti cercare un modo per fermare il Gestore. Immagino che Handler-> removeCallbacks funzionerebbe se il messaggio è in coda, ma se il Gestore è in esecuzione non sono sicuro che ciò fermerebbe l'esecuzione. –

Problemi correlati