如何安全退出HandlerThread的looper

Posted

技术标签:

【中文标题】如何安全退出HandlerThread的looper【英文标题】:How to quit HandlerThread's looper safely 【发布时间】:2013-07-30 06:23:35 【问题描述】:

我有一个 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);
  
);

我需要在某个时候退出 looper,在 60 秒或类似的时间后......所以我写:

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

我认为这会导致 looper 突然退出,所以我开始收到这个“警告”消息:

W/MessageQueue(3726): java.lang.RuntimeException: 处理程序 (android.os.Handler) 4823dbf8 在死机上向 Handler 发送消息 线程

我想避免这个错误消息,我认为我可以使用Looper.quitSafely() 方法解决它.. 但我检查了API,它不再可用。 有谁知道发生了什么? (它不像其他一些方法已弃用

有什么方法可以安全退出looper吗?谢谢!

【问题讨论】:

停止发送 handler.postDelayed(this, 5000) 延迟的 Runnables 喜欢用旗帜什么的? 也许你可以试试thread.getLooper().quitSafely()? 【参考方案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 是的,在这种情况下,您应该寻找一种方法来停止处理程序。如果消息在队列中,我猜 Handler->removeCallbacks 会起作用,但是如果正在执行 Handler,我不确定这是否会停止执行。 很抱歉没有更有用,但我不是线程和处理程序方面的专家;) 你也可以访问全局变量。【参考方案2】:

我不是Thread Guru,但这种方式可以给你方向:

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

【讨论】:

以上是关于如何安全退出HandlerThread的looper的主要内容,如果未能解决你的问题,请参考以下文章

HandlerThread总结

HandlerThread的简单分析

Android源码学习-----HandlerThread

HandlerThread原理与应用

Android 线程

在VB中,如何强制退出循环结构