Handler的处理

本文详细解析了Android中Handler的工作原理,包括消息发送、处理流程及其内部实现机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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放到消息队列中去,然后就开始处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值