美文网首页
android 中的handler消息机制

android 中的handler消息机制

作者: eliteTyc | 来源:发表于2018-11-21 15:21 被阅读0次

什么是 handler,looper,MessageQueue

  • handler :消息的发送和处理器
  • looper : 消息的传递器
  • MessageQueue:消息存放队列

一个完整的消息传递流程

  1. 当我们调用new Handler()创建handler对象之后进行消息的发送
  2. 调用handler.sendMessage,或者sendMessageDelay等等,其实最终都会调用方法中我们都会看到其实是将消息放入消息队列enqueueMessage(queue, msg, uptimeMillis);
public boolean sendMessageAtTime(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);
    }

3.那么问题来了,消息队列,也就是这个MessageQueue哪里来的?
其实消息队列是在looper初始化的时候创建的,下面的代码是looper对象中的


    private Looper(boolean quitAllowed) {
        //在这里创建了消息的队列
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

现在知道了消息队列是如何来的,这个looper对象什么时候创建的?
4.looper什么时候创建?:

  • 当我们处于主线程的时候,主线程会主动调用looper.preper方法,贴上代码
private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
    //重点是这一行代码,它调用了本地线程的工具类,创建looper对象加入这个工具类的静态成员中
        sThreadLocal.set(new Looper(quitAllowed));
    }
  • 当我们处于子线程时,当前线程中不会主动创建looper对象,这也就是为什么当我们在子线程中new handler进行使用时会出现以下异常
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

所以说当我们需要在子线程中new handler使用的时候需要先在当前子线程中调用looper.preper方法进行looper对象的创建,这样也才会创建属于当前子线程的MessageQueue否则发送到当前子线程的消息将无处存放,也就会出现上面的错误
5.looper.loop执行死循环等待消息


        for (;;) {
            //下面这行代码将是死循环,一直等待取消息
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

总结

  • 执行的整个流程就是
    线程调用looper.preper创建looper对象->looper对象创建消息队列MessageQueue用来存放消息
    线程调用looper.loop循环取消息队列中的消息
    创建handler,handler发送消息->消息进入消息队列
    handler取消息->消息出队

相关文章

网友评论

      本文标题:android 中的handler消息机制

      本文链接:https://www.haomeiwen.com/subject/xmhcqqtx.html