How to quit HandlerThread's looper safely
Asked Answered
D

2

7

I have a HandlerThread, to which I keep posting a runnable every 5 seconds. Something like this:

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

I need to quit the looper at some point, after 60 seconds or something like that.. so I write:

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

I think this causes the looper to quit abruptly, so I start getting this "warning" messages:

W/MessageQueue(3726): java.lang.RuntimeException: Handler (android.os.Handler) {4823dbf8} sending message to a Handler on a dead thread

I want to avoid this error msg, I thought that I could solve it by using the Looper.quitSafely() method.. but I checked the API and it's no longer available. Does anyone know what happened to it? (It's not deprecated like some other methods).

Is there some way I can quit the looper safely? Thanks!

Demagnetize answered 30/7, 2013 at 7:59 Comment(3)
stop sending handler.postDelayed(this, 5000) delayed RunnablesIvanivana
like using a flag or something?Demagnetize
maybe you could try thread.getLooper().quitSafely()?Volumed
C
1

You could try to use a boolean to know if the code should be executed. Something like this:

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);
Ceramist answered 30/7, 2013 at 8:17 Comment(4)
what if I have many many handlerthreads though? I mean I wouldn't wanna keep one boolean for each thread...:PDemagnetize
Yes, in that case you should look for a way to stop the Handler. I guess Handler->removeCallbacks would work if the message is in queue, but if the Handler is being executed I'm not sure if that would stop the execution.Ceramist
Sorry for not being more useful, but I'm not an expert in threading and Handlers ;)Ceramist
You can access global variables too.Ceramist
I
0

Im not Thread Guru, but this way can give you direction:

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

In your thread:

while (isRunning) {
   //...
 }

1st all you implement run method in loop (while(isRunnig){}).

On finish, you switch flag to false and "wait" for join.

Inversion answered 30/7, 2013 at 8:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.