在android中,可以使用Handler来发布/处理消息,如果我不使用HandlerThread(将其Looper传递给Handler),这是否意味着在这种情况下Handler使用MainThread(UI线程)的Looper?
如果Handler使用MainThread的Looper将会得到什么结果?可能导致mainThread被阻止?
[如果要一次执行一个后台任务,并且希望这些任务按执行顺序运行,则可以使用HandlerThread。
例如,如果要一一进行多个网络后台操作。
是的,HandlerThread有它自己的循环程序,可以创建并发布处理程序,(这样就不会阻塞主线程)。
使用这样的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,这是一种便捷的方法。
当您创建新的处理程序时,它绑定到正在创建它的线程的线程/消息队列中-参见官方文档...
[Doc说:
方便类,用于启动具有循环程序的新线程。然后可以使用循环程序创建处理程序类。请注意,仍必须调用start()。
HanderThread
类继承自Thread类,该类封装了Looper对象,因此我们不必关心Looper的打开和释放细节。就像普通线程一样,我们需要使用Looper.prepare()
和Looper.loop()
将其转换为LooperThread
。
如果我不使用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的内部:
HandlerThread在您要执行许多后台任务时很有用,因为它有自己的循环程序。通常,如果将消息发布到Handler,则它会使用MainThread的循环程序。这意味着该任务是在UI线程上执行的。但是对于HandlerThread,这些任务在工作线程上执行。您可以找到更详细的解释here
每个人似乎都解释了它的用途以及如何使用,但是忘记了解释,开发人员在使用后必须清理此线程,否则它会泄漏。使用后,您必须致电
thread.quit()
退出而不处理队列中的消息或
thread.quitSafely();
处理当前在队列中的消息。