Handler消息机制分析

主要对象

  • Looper : Class used to run a message loop for a thread
  • MessageQueue :Low-level class holding the list of messages to be dispatched by a Looper
  • Message:Defines a message containing a description and arbitrary data object that can be sent to a Handler
  • Handler:A Handler allows you to send and process {@link Message} and Runnable objects associated with a thread’s {@link MessageQueue}

过程

1. Looper,MessageQueue 对象创建

默认情况下,新创建的线程不会创建Looper,但是主线程除外,系统会自动为主线程创建Looper对象,开启消息循环。创建Looper对象会同时创建MessageQueue
Looper源码

/**
	1、通过prepare()方法 最终调用构造方法new Looper(quitAllowed)创建Looper
	2、在构造方法中,会创建MessageQueue对象,用来管理储存消息列队,先进先出
	**/
public final class Looper {
 @UnsupportedAppUsage
    final MessageQueue mQueue;

    public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {  //一个线程一个looper
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

	 private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
}
2.Hanlder创建

当我们需要进行消息发送时,需要创建Handler

private Handler handler=new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };

Handler构造方法,创建Handler会获取到当前线程的Looper和MessageQueue作为属性引用

public Handler(@Nullable Callback callback, boolean async) {
   		···
        mLooper = Looper.myLooper();
        mQueue = mLooper.mQueue;
 		···
    }
3.消息创建
   Message msg=Message.obtain();
   msg.what=1111;
    msg.obj="helloworld";
4.消息发送

使用handler发送消息

 handler.sendMessage(msg);

发送消息会调用Handler如下方法,最终会调用MessageQueue的enqueueMessage()方法;

  public final boolean sendMessage(@NonNull Message msg) {
        return sendMessageDelayed(msg, 0);
    }
    
 public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
    
  public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }

 private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
            long uptimeMillis) {
        msg.target = this;
        msg.workSourceUid = ThreadLocalWorkSource.getUid();

        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

并且msg.target = this; Message中属性target设置为该handler

public final class Message implements Parcelable {
    @UnsupportedAppUsage
    /*package*/ Handler target;
}

调用queue.enqueueMessage(msg, uptimeMillis)方法,将message加入到消息列队当中

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;
    }

然后Looper.loop()方法会一直循环从messagequeue中取消息
for (;? { //死循环,调用queue.next(),去取MessageQueue中的消息

 public static void loop() {
        final Looper me = myLooper();
     	···
        for (;;) {  //死循环,调用queue.next(),去取MessageQueue中的消息
            Message msg = queue.next(); // might block
         
     		···
            try {
                msg.target.dispatchMessage(msg); //最终会走这里,调用Handler的dispatchMessage来进行消息的分发
                if (observer != null) {
                    observer.messageDispatched(token, msg);
                }
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } catch (Exception exception) {
                if (observer != null) {
                    observer.dispatchingThrewException(token, msg, exception);
                }
                throw exception;
            } finally {
                ThreadLocalWorkSource.restore(origWorkSource);
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
         ···
        }
    }

最终会走这里,调用Handler的dispatchMessage来进行消息的分发
		msg.target.dispatchMessage(msg);

handler的dispatchMessage会走handleMessage回调,并且将消息传入

 /**
     * Handle system messages here.
     */
    public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值