为什么要在Android中使用HandlerThread

问题描述 投票:15回答:6

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

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

android android-handler android-handlerthread
6个回答
16
投票

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

例如,如果要一一进行多个网络后台操作。

是的,HandlerThread有它自己的循环程序,可以创建并发布处理程序,(这样就不会阻塞主线程)。


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,这是一种便捷的方法。

当您创建新的处理程序时,它绑定到正在创建它的线程的线程/消息队列中-参见官方文档...


5
投票

[Doc说:

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

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


4
投票

如果我不使用HandlerThread(将其Looper传递给Handler,这是否意味着在这种情况下Handler使用MainThread(UI线程)的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?


1
投票

HandlerThread在您要执行许多后台任务时很有用,因为它有自己的循环程序。通常,如果将消息发布到Handler,则它会使用MainThread的循环程序。这意味着该任务是在UI线程上执行的。但是对于HandlerThread,这些任务在工作线程上执行。您可以找到更详细的解释here


0
投票

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

thread.quit()

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

thread.quitSafely();

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

© www.soinside.com 2019 - 2024. All rights reserved.