Handler源码认知

Handler是面试一定会问得机制,每次都能够打上来,但是答的很浅,只是说了大概的一个工作机制,画了个图从源码的角度加深自己的理解吧。首先上图





上面是大概的一个工作机制,从源码的角度来说其实没有太多重要的地方,主要就关注这么几个类

Message:承载着消息的对象。

MessageQueue:存放消息的队列

Handler:负责发送消息和接收消息的对象

Looper:消息循环机制

通常都会使用消息池机制,如下可以获得一个Message对象

Message.obtain(this)obtain()
message.sendToTarget();


Message message = handler.obtainMessage();
//从源码的角度来说其实在里面做了那么一件事情,它会把当前的那个handler传进来,到之后后面的message可以直接调用
//message.sendToTarget();

public static Message obtain(Handler h) {
        Message m = obtain();
        m.target = h;

        return m;
    }
在obtain这个方法里面又干了这么一件事情
  public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }
//看看就能够知道了,第一次创建的时候是没有消息池的,直接new 了一个对象出去,在后面会把该消息放入消息池
//这里完成了消息的初始化,当执行完自己的逻辑之后调用message.sendToTarget();通过保存在message内部的
//handler发送消息到消息池里面
   boolean enqueueMessage(Message msg, long when) {
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
        if (msg.isInUse()) {
            throw new IllegalStateException(msg + " This message is already in use.");
        }

        synchronized (this) {
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w("MessageQueue", e.getMessage(), e);
		//在这里实现了消息的回收,实际上就是把消息放回消息池
                msg.recycle();
                return false;
            }

            msg.markInUse();
            msg.when = when;
            Message p = mMessages;
            boolean needWake;
            if (p == null || when == 0 || when < p.when) {
                // New head, wake up the event queue if blocked.
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;
            } else {
                // Inserted within the middle of the queue.  Usually we don't have to wake
                // up the event queue unless there is a barrier at the head of the queue
                // and the message is the earliest asynchronous message in the queue.
                needWake = mBlocked && p.target == null && msg.isAsynchronous();
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }

            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
    }

以上就是对handler的理解


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值