Handler机制相关学习文档

介绍
Handler机制的作用:实现线程间通信的
如何实现Handler机制:
简单模型
Handler机制相关学习文档_第1张图片

HandlerLooperMessageQueueMessage
Handler:消息的处理者或者消费者,持有Looper的引用
Looper:通过loop()不停的读取MessageQueue消息,让Message.target(Handler)进行处理消息
MessageQueue:由链表实现的消息队列,方便插入和删除
Message:关键字段

  • when:用作消息延时使用
  • mCallBack:消息回调监听
  • target:自定义其为消息来源,当为null表示屏障消息
  • What、arg1、arg2、obj等

消息类型

  • 同步消息:按顺序执行的普通消息
  • 屏障消息:开启屏障、关闭屏障,开始屏障:表明要优先执行异步消息了,取消屏障:继续执行普通消息
  • 异步消息:优先执行的消息,如帧率更新ui

发送消息
非延时消息:when= 当前时间 +0
延时消息:when= 当前时间+延时时间

public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

入队列:消息插入到应该在的位置,如果队列正在阻塞中,唤醒队列

**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(TAG, 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;
}

出队列:messageQueue.next()

  • 普通消息:判断when和当前时间比,大于当前时间开始阻塞知道,时间到达,反之直接当条消息
  • 屏障消息:target为null表示屏障消息,遍历出消息队列里吗的第一条异步消息执行
    if (msg != null && msg.target == null) {
    // Stalled by a barrier. Find the next asynchronous message in the queue.
    do {
    prevMsg = msg;
    msg = msg.next;
    } while (msg != null && !msg.isAsynchronous());
    }**

分发消息
Looper的loop方法调用
message.target.dispatchMessage()

Handler的方法dispatchMessage()

public void dispatchMessage(Message msg) {
    if (msg.callback != null) {//当消息中有callback直接回调消息中的
        handleCallback(msg);
    } else {//反之
        if (mCallback != null) {//当前handler全局中有定义Callback
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);//回调该方法
    }
}

高级问题:
如何监听方法耗时,通过handler机制实现Printer接口

if (logging != null) {
    logging.println(">>>>> Dispatching to " + msg.target + " " +
            msg.callback + ": " + msg.what);
}
if (logging != null) {
    logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}

如何屏障消息区分
target=null

如何区分异步消息
isAsynchronous()方法

如何实现帧率优先
Vsync垂直同步信号监听,Choreographer.FrameCallback doFrame监听接口回调时,先发送屏障消息插入在对列头,然后在发送异步消息

你可能感兴趣的:(android,学习笔记,handler机制,handler)