如何安全退出HandlerThread的looper

7

我有一个HandlerThread,我每5秒就往里面发布一个可运行的任务。代码如下:

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: Handler (android.os.Handler) {4823dbf8} 在发送消息给已停止的线程上

我想要避免这个错误消息,我想通过使用 Looper.quitSafely() 方法来解决它...但我查看了API,发现它不再可用。有人知道发生了什么吗?(它不像其他某些方法一样被弃用)。

是否有某种方法可以安全地退出循环程序?谢谢!


停止发送 handler.postDelayed(this, 5000) 延迟的 Runnables。 - pskink
像使用标志或其他东西吗? - sundie
也许你可以尝试使用 thread.getLooper().quitSafely()? - Richard
2个回答

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);

如果我有很多处理程序线程怎么办?我的意思是我不想为每个线程保留一个布尔值... :P - sundie
是的,在这种情况下,您应该寻找一种停止Handler的方法。如果消息在队列中,我猜Handler->removeCallbacks会起作用,但如果Handler正在执行,我不确定是否会停止执行。 - PX Developer
抱歉我没能提供更多帮助,因为我不是线程和处理程序方面的专家 ;) - PX Developer
你也可以访问全局变量。 - PX Developer

0

我不是线程大师,但这种方式可以给你指导:

 ...
_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(isRunning){})。

完成后,将标志切换为false并“等待”join


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接