异步消息-Handler机制总结

Looper就是上一节提到的sThreadLocal这个容器,sThreadLocal是线程所持有的,可以保证线程和其他线程是独立看来的,通过调用.get方法可以获取我们相应的Looper对象 。Looper对象的创建在构造方法中还创建了MessageQueue消息队列,Looper对象已经完成了MessageQueue对象的创建,怎么去更好的完成他的管理呢?这时候管理的方法Looper方法当中的轮询方法,是如何轮询消息队列获取消息交给handler的呢?

首先通过myLooper这个方法获取一个Looper对象,myLooper也是一样的原理,通过sThreadLocal来获取不同的Looper对象,然后会对这个Looper对象是否为空进行判断,如果为空的话抛出异常。Looper.prepare这个方法其实就是在我们创建Looper前调用的。如果Looper不是为空的,说明Looper和Looper内部的消息队列是有的,然后进行赋值

这是个死循环,说明Looper会不断从消息队列中去获取消息,如果不为空就会调用msg.target.dispatchMessage这个方法。target这个变量就是handler对象,如果我们的消息不为空,就说明要交给我们的handler来进行处理。handler一个是发送消息一个是解决处理消息,dispatchMessage就是用来解决消息的。
回到handler看一下dispatchMessage是怎样做的:

首先判断msg.callback是否为空,如果不是为空就会调用handleCallback这个方法来处理消息。
然后会判断mCallback是否为空,不为空的话调用handleMessage这个方法来处理消息。mCallback就是个接口,接口中有一个非常重要的方法handleMessage。大家经常在主线程中创建handler的时候,都会去重写handleMessage表示主线程接收到了子线程发送消息的时候如何去处理他的异步消息。

handleCallback这个方法内部特别简单,就是调用内部传进来的run方法,表示在子线程做一些操作。
到这里handler整体就算是过了一一遍了。
我们再去说一下handler的主要流程:

Handler的整体工作流程:
首先,我们要创建一个Looper对象,Looper对象的作用就是不断的从MessageQueue消息队列中去获取Message,这个Message哪里来的呢?就是由Handler发送的。handler可以发送消息给MesaageQueue,插入到他的队列当中,他的第二个作用就是能够从Looper不断轮询MessageQueue中获取消息之后交给Handlr,然后再由handler来进行消息的处理。这就是Handler一个完整的工作机制。
最后再总结几个要点:
Looper类主要是为每个线程开启的单独的消息循环,因为内部是通过sThreadLocal这个线程控制来进行存储,默认情况下Android新诞生的线程是没有开启消息循环的,所以说线程中要使用Handler,必须要调用Looper的prepare方法。但是主线程除外,因为主线程中系统已经为我们创建了一个Looper对象。
Handler是Looper的一个接口,用来向指定的Looper 中的MessageQueue发送消息。
在非主线程中直接new Handler()是不可以的,原理就是因为handler需要发送消息到MessageQueue,而这个所在的线程中没有MessageQueue,MessageQueue是Looper管理的,所以说如果你想创建Handler,必须在该线程中创建好Looper这个对象,这样就可以直接new Handler()。