为什么在Android中使用HandlerThread

时间:2012-05-23 03:13:51

标签: android android-handler android-handlerthread

在android中,Handler可用于发布/处理消息,如果我不使用HandlerThread(将其Looper传递给Handler),这是否意味着在这种情况下Handler使用MainThread(UI Thread)的Looper?

如果Handler使用MainThread的Looper会得到什么结果?可能导致mainThread被阻止?

6 个答案:

答案 0 :(得分:16)

如果您希望一次执行一个后台任务,并且希望这些任务按执行顺序运行,您可以使用HandlerThread。

例如,如果您想逐个进行多个网络后台操作。

是的,HandlerThread有它自己的looper并且可以创建并发布处理程序,(因此它不会阻止主线程。)

答案 1 :(得分:6)

使用HandlerThread的正常方式如下:

HandlerThread thread = new HandlerThread("A Handler Thread");
thread.start();
Handler handler = new Handler(thread.getLooper()){
    @Override
    public void handleMessage(Message msg) 
    {
    //....
    }
};

因为HandlerThread可以为Handler创建一个Looper,所以它是一种方便的方法。

当你创建一个新的Handler时,它被绑定到创建它的线程的线程/消息队列 - 请参阅官方文档......

答案 2 :(得分:4)

正如Doc所说:

  

用于启动具有looper的新线程的方便类   然后可以使用循环器来创建处理程序类   请注意,仍然必须调用start()。

HanderThread类继承自Thread类,它封装了Looper对象,因此我们不关心Looper打开和释放细节。与普通线程一样,我们需要使用Looper.prepare()Looper.loop()将其转换为LooperThread

答案 3 :(得分:4)

  

如果我不使用HandlerThread(将其Looper传递给Handler),这是否意味着Handler使用MainThread(UI Thread)的Looper?

查看Handler

的文档
Handler ()
  

默认构造函数将此处理程序与当前线程的Looper相关联。

如果您当前的线程是MainThread,它使用MainThread(UI Thread)Looper。

要将Handler显式关联到MainThread(UI线程),请编写下面的代码。

Handler  mHandler = new Handler(Looper.getMainLooper();

如果你写的如下,它使用HandlerThread Looper。

HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
Handler requestHandler = new Handler(handlerThread.getLooper());

如果您在Runnable任务中有任何网络IO操作,则无法使用主线程循环器。在这种情况下,HandlerThread可以方便地发布执行网络IO操作的Runnable任务。

您可以找到示例代码@ How do I fix android.os.NetworkOnMainThreadException?

  

如果Handler使用MainThread的Looper会得到什么结果?可能导致mainThread被阻止?

如果您向MainThread Looper发送许多事件,它们将在MainThread(UI线程)本身上执行。如果提交的任务花费更多时间执行,MainThread将被阻止。

查看以下帖子,了解Looper

的内部信息

What is the purpose of Looper and how to use it?

答案 4 :(得分:1)

当你想执行很多后台任务时,HandlerThread很有用,因为它有自己的循环器。通常,如果您向Handler发布消息,它将使用MainThread的looper。这意味着该任务在UI线程上执行。但是在HandlerThread的情况下,这些任务在工作线程上执行。您可以找到更详细的解释here

答案 5 :(得分:0)

每个人似乎都在解释它的功能以及如何使用它,但是忘记了解释该线程,在开发人员使用后需要清理,否则会泄漏。使用后,您必须致电

thread.quit()

退出而不处理队列中的消息或

thread.quitSafely();

处理当前在队列中的消息。