Handler的处理

Handler的官方解释大致意思如下:

Handler是一种能够发送和处理与消息队列关联的MessageRunnable的一种对象。它隶属于调用Handler对象的线程,自它创建伊始,它就在当前线程发送消息到当前线程的消息队列,并且负责处理线程消息队列的消息。

Handler的用法主要有两种:其一,发送消息,其二,在另外一个线程处理消息。

对其一:

 post(Runnable)postAtTime(Runnable, long)postDelayed(Runnable, long)sendEmptyMessage(int)sendMessage(Message)sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) 这些方法主要用来发送消息,其中,post version主要是发送Runnable,而sendMessage version则是用来发送消息,然后在handlerHandleMessage中处理。

如何处理的呢?最后一段非常关键:当我们创建了一个应用程序进程,它内部就开启了一个处理消息的Looper.

new一个Handler的时候,

mLooper = Looper.myLooper();

public static final Looper myLooper() {

        return (Looper)sThreadLocal.get();

}

mQueue = mLooper.mQueue;

mCallback = callback;

获取当前进程的Looper,然后获取它的消息队列,这样就将一个消息加入了消息队列,这个Looper开启类似下面,先运行Run方法,在Run方法中Looper.prepare,之后进入一个无限循环,Looper.loop(),在这里处理消息。在处理消息时调用callback,也就是HandleMessage或者Run开始处理。

因此,在用Handler的时候有两点需要注意:

一是callback函数,二时Post/sendMessagecallback为处理Message,而Post/sendMessage则是发送Message

相关代码:

发送消息:

public final boolean sendMessage(Message msg)

{

        return sendMessageDelayed(msg, 0);

}-------->

---->

 public final boolean sendMessageDelayed(Message msg, long delayMillis)

 {

       if (delayMillis < 0) {

           delayMillis = 0;

       }

       return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);

 }------>

-------->

public boolean sendMessageAtTime(Message msg, long uptimeMillis)

{

        boolean sent = false;

        MessageQueue queue = mQueue;

        if (queue != null) {

            msg.target = this;

            sent = queue.enqueueMessage(msg, uptimeMillis);

        }

        else {

            RuntimeException e = new RuntimeException(

                this + " sendMessageAtTime() called with no mQueue");

            Log.w("Looper", e.getMessage(), e);

        }

        return sent;

}

可见发送消息就是将Message加入消息队列。

处理消息:

public static final void loop() {

        Looper me = myLooper();

        MessageQueue queue = me.mQueue;

        

Binder.clearCallingIdentity();

        final long ident = Binder.clearCallingIdentity();

        

        while (true) {

            Message msg = queue.next(); //获取下一个Message,可能会block

            if (msg != null) {

                if (msg.target == null) {

                   return;

                }

                msg.target.dispatchMessage(msg);

             

                final long newIdent = Binder.clearCallingIdentity();

                if (ident != newIdent) {

                    Log.wtf("Looper", "Thread identity changed from 0x"

                            + Long.toHexString(ident) + " to 0x"

                            + Long.toHexString(newIdent) + " while dispatching to "

                            + msg.target.getClass().getName() + " "

                            + msg.callback + " what=" + msg.what);

                }

                

                msg.recycle();

            }

        }

也就是Loop循环不断从消息队列中获取消息进行处理:其实就是调用callback的过程。

Runnable处理流程:

现在来分析:发送流程:

Runnable runa = new Runnable() {

           public void run() {

// TODO Auto-generated method stub

}

}

然后Handler mHandler = new Handler();

mHandler.post(runna);

public final boolean post(Runnable r)

{

       return  sendMessageDelayed(getPostMessage(r), 0);

}

官方解释是:Causes the Runnable r to be added to the message queue.也就是将Runnable加入到Message队列,怎么变成消息的呢?

接着往下看:

public final boolean post(Runnable r)

{

       return  sendMessageDelayed(getPostMessage(r), 0);    

}----->

sendMessageDelayed(getPostMessage(r), 0)--->

------>

public final boolean sendMessageDelayed(Message msg, long delayMillis)

{

        if (delayMillis < 0) {

            delayMillis = 0;

        }

        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);

 }

在上一步,决定何时发送,是否延时发送。

getPostMessage()函数原型如下:

private final Message getPostMessage(Runnable r) {

        Message m = Message.obtain();

        m.callback = r;

        return m;

}

在这里我们看到,Message.obtain()获取一个Message实例,然后将Runnable加入到Messagecallback中,也就是封装成一个Message了。之后在大循环中进行处理。

到此,对于Handler发送Message也就很容易理解了,只不过把runnable改变成Message放到消息队列中去,然后就开始处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java中的处理器(Handler)是一种机制,用于将任务(也称为消息)分派给线程进行处理。它可以用于在不同线程之间传递消息,从而实现线程间的通信和同步。 Java中的处理器通常与线程池配合使用。当应用程序需要执行一项任务时,它会将任务封装成一条消息,然后将该消息发送到指定的处理器中。处理器会将消息放入一个消息队列中,并由线程池中的线程不断从队列中取出消息进行处理。这种方式可以有效地利用线程资源,提高系统的并发能力。 要使用Java的处理器机制,你需要创建一个继承自`android.os.Handler`的类,并实现它的`handleMessage`方法。这个方法用于处理从消息队列中取出的消息。你还可以重写`dispatchMessage`方法来定制如何分派消息。当你需要执行一项任务时,你可以使用`sendMessage`方法将任务封装成消息并发送给处理器。 使用处理器的一个优点是,你可以使用它在不同线程之间传递消息,从而实现线程间的通信和同步。但是,你需要 ### 回答2: Java中的Handler是一个重要的处理机制,用于处理线程之间的通信和消息传递。Handler可以认为是发送消息和处理消息的中介者。 在Java中,一个Handler对象可以与一个特定的线程相关联。当一个线程想要向另一个线程发送消息时,它可以通过Handler对象发送消息。要使用Handler,我们需要首先创建一个Handler对象,并将其与接收消息的线程关联起来。一旦关联完成,我们可以使用Handler的post方法发送消息给接收线程。 接收线程可以通过重写HandlerhandleMessage方法来处理接收到的消息。当接收线程收到消息时,它会自动调用handleMessage方法,并将收到的消息作为参数传递给该方法。这样,处理线程就可以根据接收到的消息类型执行相应的操作。 Handler处理机制还具有一些其他的特性。例如,我们可以为Handler设置定时任务,使其在指定的时间间隔内执行某个任务。此外,我们还可以通过Handler实现线程之间的同步,从而避免并发访问共享资源时的竞争条件。 总而言之,Java Handler是一种用于处理线程间通信和消息传递的重要机制。通过Handler,不同的线程可以安全地发送和接收消息,并实现特定的处理逻辑。同时,Handler还具备定时任务和线程同步的功能,使得线程之间的通信更加稳定和有序。 ### 回答3: Java Handler 是用来处理线程之间通信的机制,它允许你发送和处理消息或者任务。在 Java 中,线程之间的通信一般是通过共享内存或者锁来实现的。然而,这些方法可能会导致竞态条件或者死锁的问题。 相比之下,Java Handler 使用了消息队列的方式来处理线程之间通信。处理线程通过在消息队列中发送消息或者任务,然后由接收线程从消息队列中读取并处理这些消息或者任务。 使用 Java Handler 的好处之一是它可以帮助开发者解决线程之间通信时的竞态条件和死锁问题。由于消息队列是基于先进先出的原则,处理线程可以按顺序读取和处理消息,避免了竞态条件的发生。 另一个好处是 Java Handler 支持异步处理消息或者任务。处理线程可以继续执行其他任务,并在消息或者任务准备就绪时进行处理。这可以提升程序的响应性能和处理效率。 使用 Java Handler 还可以实现线程之间的解耦。发送消息的线程不需要知道接收消息的线程是谁,只需要发送消息到相应的 Handler。这样可以简化代码的编写和维护,并提高代码的复用性和可扩展性。 总的来说,Java Handler 提供了一种可靠且高效地处理线程之间通信的机制。它通过使用消息队列来解决竞态条件和死锁问题,并支持异步处理消息和任务,同时还可以实现线程之间的解耦。这使得开发者能够更好地管理和控制多线程程序,增强了程序的可靠性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值