美文网首页
Android消息机制小结

Android消息机制小结

作者: r09er | 来源:发表于2018-03-20 13:47 被阅读10次
Android消息机制:
  • 主要是指Handler的运行机制,同时Handler需要MessageQueue和Looper的支持.
Handler的主要作用:
  • 将一个任务切换到某个指定的线程中执行
Android中使用消息机制的原因:
    1. Android系统规定UI只能在主线程进行,如果在非主线程中执行会抛出异常,线程的检验由ViewRootImpl的checkThread方法完成.
void checkThread() {
        if (mThread != Thread.currentThread()) {
            throw new CalledFromWrongThreadException("Only the original thread that created a view hierarchy can touch its views.");
        }
    }
    1. 主线程不能执行耗时操作,只能通过子线程进行耗时操作后通知界面刷新.
Handler工作过程:
Handler工作过程.png
MessageQueue创建和工作原理
  • MessageQueue虽然名为消息队列,但是内部的数据结构使用的是单链表,因为单链表插入和删除效率较高.
  • MessageQueue主要作用就是对消息进行插入和读取操作,插入方法为enqueueMessage(),读取方法为next()
  • MessageQueue在Looper创建的时候创建

由于Looper是使用ThreadLocal保存的,由此得知每一个线程都只有一个Looper和一个MessageQueue

 private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        ...
    }
  • Handler通过post或者send方法将消息发送到MessageQueue,由于Handler所有的post和send相关方法都会最终执行到enqueueMessage方法,而Handler的enqueueMessage方法会调用MessageQueue的enqueueMessage方法,所以就将消息加入到了消息队列中.
 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }
  • 在MessageQueue的enqueueMessage方法中,主要的操作只是将所有的消息进行单链表的插入操作.

  • 在MessageQueue的next()方法中,对队列进行无限循环,直到有新的消息插入,next方法就会返回这条消息,并从链表中删除这条消息.

Looper的工作原理
  • 在消息机制中,MessageQueue扮演的角色只是一个消息存储的对象.而Looper就是不断遍历从MessageQueue,查询是否有信息消息加入,如果有就会通知Handler进行处理,否则就一直在循环遍历.

  • 在手动创建的线程中默认是没有Looper的,因为Thread是Java的类,而Looper是Android提供的类,所以手动创建Thread后,需要提供一个Looper对象,才能正确的开启消息轮训.

  • 创建Looper的方法,通过Looper的静态方法prepare初始化,然后调用loop方法进行小心轮训.

new Thread(){
            @Override
            public void run() {
                Looper.prepare();
                Handler handler = new Handler();
                Looper.loop();
            }
        }.start();
  • Looper中最重要的方法是loop,只有调用了loop方法才能开启对MessageQueue的轮训,对消息进行处理.在loop中会调用MessageQueue的next方法来获取消息,然后通过调用Handler的dispatchMessage方法进行消息的处理,而dispatchMessage方法是在创建Looper的线程中执行的,所以这样就将任务切换到了不同的线程中去了.
  • Handler的创建必须有Looper,经常使用的空参数Handler其实已经默认获取到了主线程的Looper.
Handler工作原理
  • Handler的工作主要包含消息发送和消息接收过程.
  • 消息的发送可以通过一系列post和send方法实现,不过最终也是会调用到sendMessageAtTime方法.
  • Handler发送消息的过程其实只是向MessageQueue中插入了一条消息,Looper会调用MessageQueue的next方法获取到这条消息,Looper获取到消息后,再交给Handler进行处理,即Handler的dispatchMessage方法会被调用,这样消息的发送过程就完成了.进入到消息处理.
Handler的dispatchMessage具体执行流程
 public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

在消息处理阶段,优先判断Message的CallBack是否为null,而这个callBack实际上就是handler的post方法传递进行来Runnable,然后就调用handleCallback方法,其实只是简单的调用Runnable中的run方法.

 private static void handleCallback(Message message) {
        message.callback.run();
    }

当Callback为空,则检查mCallback接口是否为null,不为null就调用mCallback的handleMessage方法.mCallback其实是Handler的一个接口,可以在创建Handler的时候作为构造参数.

//CallBack接口使用方法

 Handler handler = new Handler(new Handler.Callback() {
                    @Override
                    public boolean handleMessage(Message msg) {
                        return false;
                    }
                });

调用了mCallback的handleMessage方法后,如果返回了true,这条消息已经被正确处理,如果返回false,最终调用Handler的handleMessage方法,结束消息处理过程.


Handler消息处理流程图.png

相关文章

网友评论

      本文标题:Android消息机制小结

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