处理程序是否为线程?如果是,我们如何从此Handler(线程)更新UI?
如果我们使用Looper概念,则可能。在这种情况下,它适用于任何线程吗?我对这些Threads,Handlers和Loopers非常困惑。有人可以用一个例子解释一下吗? 处理程序是一个线程与否?如果是,我们如何从此Handler(线程)更新UI。
如果我们使用Looper概念,那么它可能适用于任何线程吗?我对这个Thread,Handler和Looper非常困惑。有人可以用一个例子解释一下吗?
问题" What is the difference between a Thread and a Handler"仅涉及处理程序和线程,但不解释Loopers及其行为。接受的答案是"另一方面,处理程序是后台线程,允许您与UI线程进行通信(更新UI)",但根据" ben75&#34的答案;在下面,处理程序不是一个线程。因此,我认为这不是该问题的重复。
答案 0 :(得分:6)
前提:处理程序不是线程。
Looper
是与创建它的Thread
关联的对象。正如你可以用它的名字猜测的那样Looper
会循环一些东西,但是循环过去?通过消息队列也与同一个线程相关联。
下一个问题是:我如何在消息队列中添加内容?
这是Handler
。 Handler
始终与Looper
相关联(哪一个?我们稍后会看到它)。 Handler
可以扮演2个角色(也许这可能是令人困惑的原因)
处理程序的第一个角色:您必须使用它将消息发布到它的关联Looper(实际上是它的消息队列)。您可以使用各种Handler.sendMessage*
(或Handler.post*
)方法之一来执行此操作。 (并注意sendMessageDelayed / postDelayed方法,允许您发布Message / Runnable以便将来处理)
与处理程序相关的Looper是什么?非常简单:如果你没有指定它,当前Thread的Looper;但你可以使用带有Looper的构造函数:new Handler(Looper looper)
,在这种情况下,处理程序与参数中的looper相关联。
此时,我们知道:
现在,让我们看看第二部分:消息处理/消息处理。
首先,让我们看一下Looper
循环它的消息队列。
队列中是否有消息?是的(即在某个时候,Handler
发布了它。)
是时候处理此消息了(如果它是用postDelayed发布的)?如果没有,请稍等一下。如果是时候:让我们发送这条消息。
请记住,我告诉Handler有两个角色......这里是Handler的第二个角色:一个Handler(由它的名字表示)可以处理消息。为了能够处理自定义消息,您必须继承Handler
类并实现handleMessage(Message)
方法。
因此,Looper
将简单地调用发布消息的Handler的handleMessage
,并且它的作业(即调度消息)已完成(Looper可以继续执行下一个消息)队列)。
此时你可能会问自己:“好吧,我看到了延迟信息的兴趣,但为什么我应该把所有这些东西用于立即做的事情?”
请注意,Looper
与一个Thread
相关联,handleMessage
将在此Thread
中调用。另一方面,可以从另一个线程调用Handler.post*
。所以这个机制也非常方便从线程Y安排线程X中的作业。(如果作业影响UI并且必须在UI-Thread中运行,则特别有用)
最后的注释
在Android上,有一个与主线程(即UI线程)相关联的主Looper。您可以使用Looper.getMainLooper()
获取对它的引用,因此您可以创建与主Looper关联的处理程序:
Handler myHandler = new Handler(Looper.getMainLooper());
并且您可以将消息从任何线程发布到UI线程
您并不总是需要显式创建消息才能使用此机制。您可以轻松地将Runnable
发布到Handler
,在这种情况下,您甚至不需要覆盖handleMessage(Message)
,因为处理程序的默认实现只会执行Runnable
}(在引擎盖下:创建message并将Runnable与之关联)
默认情况下,每个线程都没有Looper(默认情况下,UI-Thread中只有一个准备好的)。要为当前线程准备Looper:调用Looper.prepare()
答案 1 :(得分:0)
处理程序:
Handler允许您发送和处理Message和Runnable对象 与线程的MessageQueue相关联。每个Handler实例都是 与单个线程和该线程的消息队列相关联。什么时候 你创建一个新的Handler,它绑定到线程/消息队列 正在创建它的线程 - 从那时起,它将传递 消息和runnables到该消息队列并按它们执行它们 走出消息队列。
现在,如果您想要从不是主线程的其他线程更新UI,您将首先在主线程中创建Handler
并将其传递到任何后台线程。在后台线程中,您将使用post (Runnable r)
方法将消息发送回主线程,因为(阅读上面的段落):) Handler
s不是线程,虽然。
线程:
线程是程序中执行的线程。
只是一个通用的后台处理任务。
Looper:
Looper是一个用于执行Messages(Runnables)的类 一个队列。正常线程没有这样的队列,例如简单的线程呢 没有任何队列。它执行一次并在方法执行后执行 完成后,线程将不会运行另一个消息(Runnable)。
来源:
What is the purpose of Looper and how to use it?
What is the difference between a Thread and a Handler