Handler是一个线程与否,以及Looper与处理程序和线程的作用是什么?

时间:2014-10-13 14:05:09

标签: android multithreading android-handler android-looper

处理程序是否为线程?如果是,我们如何从此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的答案;在下面,处理程序不是一个线程。因此,我认为这不是该问题的重复。

2 个答案:

答案 0 :(得分:6)

前提:处理程序不是线程。

Looper是与创建它的Thread关联的对象。正如你可以用它的名字猜测的那样Looper会循环一些东西,但是循环过去?通过消息队列也与同一个线程相关联。

下一个问题是:我如何在消息队列中添加内容?

这是HandlerHandler始终与Looper相关联(哪一个?我们稍后会看到它)。 Handler可以扮演2个角色(也许这可能是令人困惑的原因)

处理程序的第一个角色:您必须使用它将消息发布到它的关联Looper(实际上是它的消息队列)。您可以使用各种Handler.sendMessage*(或Handler.post*)方法之一来执行此操作。 (并注意sendMessageDelayed / postDelayed方法,允许您发布Message / Runnable以便将来处理)

与处理程序相关的Looper是什么?非常简单:如果你没有指定它,当前Thread的Looper;但你可以使用带有Looper的构造函数:new Handler(Looper looper),在这种情况下,处理程序与参数中的looper相关联。

此时,我们知道:

  • 一个Looper与一个且只有一个Thread相关联
  • 一个Looper循环遍及它的相关消息队列
  • 因此:有一个与一个线程关联的消息队列(只要我们有一个线程的Looper)
  • 处理程序始终与一个Looper相关联
  • 可以使用Handler将消息发布到消息队列

现在,让我们看看第二部分:消息处理/消息处理。

首先,让我们看一下Looper循环它的消息队列

队列中是否有消息?是的(即在某个时候,Handler发布了它。) 是时候处理此消息了(如果它是用postDelayed发布的)?如果没有,请稍等一下。如果是时候:让我们发送这条消息。

请记住,我告诉Handler有两个角色......这里是Handler的第二个角色:一个Handler(由它的名字表示)可以处理消息。为了能够处理自定义消息,您必须继承Handler类并实现handleMessage(Message)方法。

因此,Looper将简单地调用发布消息的Handler的handleMessage,并且它的作业(即调度消息)已完成(Looper可以继续执行下一个消息)队列)。

此时你可能会问自己:“好吧,我看到了延迟信息的兴趣,但为什么我应该把所有这些东西用于立即做的事情?”

请注意,Looper与一个Thread相关联,handleMessage将在此Thread中调用。另一方面,可以从另一个线程调用Handler.post*。所以这个机制也非常方便从线程Y安排线程X中的作业。(如果作业影响UI并且必须在UI-Thread中运行,则特别有用)

最后的注释

  • UI-thread是一等公民:

在Android上,有一个与主线程(即UI线程)相关联的主Looper。您可以使用Looper.getMainLooper()获取对它的引用,因此您可以创建与主Looper关联的处理程序:

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

并且您可以将消息从任何线程发布到UI线程

  • 你真的应该使用消息和继承Handler来使用它吗?不(不总是)

您并不总是需要显式创建消息才能使用此机制。您可以轻松地将Runnable发布到Handler,在这种情况下,您甚至不需要覆盖handleMessage(Message),因为处理程序的默认实现只会执行Runnable }(在引擎盖下:创建message并将Runnable与之关联)

  • 必须准备好Looper(接收消息)

默认情况下,每个线程都没有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

相关问题