Handler机制源码分析之Handler

1. Handler的一些常见字段

要想理解Handler的一些方法,知晓Handler的一些字段属性,是必不可少的,接下来看看Handler的一些字段吧.


Handler机制源码分析之Handler_第1张图片
handler中的字段.png

2. Handler的构造方法

一般来说我们在创建Handler实例的时候都会使用
Handler handler=new Handler();这种使用方法.
其内部的实现是这样的

Handler机制源码分析之Handler_第2张图片
无Looper的构造方法01.png

可以看到无参的构造方法内部是调用了一个有两个参数的构造方法,并且第一个参数是Callback接口,而第二个就是mAsync一个boolean类型的字段了.而其最终都会调用一个构造方法.如下:
Handler机制源码分析之Handler_第3张图片
无Looper的构造方法00.png

可以看到上半部分就是各种内存泄漏的判断,并打印到日志中.之后就将当前线程的Looper和Handler里的mLooper关联了.如果为空则抛出异常,** 所以再创建Handler的实例之前, 一定要确保该线程存在Looper的实例!!! **.

既然存在Handler的无Looper的构造方法,那么就肯定有带Looper的构造方法.Handler带Looper的构造方法有几个,但最终都会调用一个方法,所以就直接看最后调用的吧.

Handler机制源码分析之Handler_第4张图片
有Looper的构造方法00.png

最终都会调用这个方法,可以看到,只是将传过来的参数赋值给Handler的各个字段而已,值得注意的是,这个还会将与Looper绑定的MessageQueue与Handler中的mQueue绑定,因为** Looper在被创建的时候会与当前线程和绑定,并且会创建一个MessageQueue实例 **.所以我们平常在非主线程使 Looper.prepare()创建Looper实例的时候,不需要自己创建MessageQueue实例,其内部源码已经帮我们实现了.

3. 使用Handler发送消息

接下来就是使用Handler发送消息了,Handler发送消息的方法也有很多,发送Message消息的有7个,发送Runnable消息的有5个,其实发送Runnable消息就是将其字段,赋给Message中的callback字段而已.让我们具体来看一看吧.

首先是发送Message消息,send方法

Handler机制源码分析之Handler_第5张图片
发送Message.png

发送Message消息一共有7个方法,最后会执行2个方法.所以我就先选取了几个常用的,这里就是我们一般会发送Message使用的几个方法.可以看到可以直接传一个Message对象,也可以直接发一个空消息,或者带有延迟的空消息等,值得注意的是,** 在发送非Message对象的时候,里面会直接使用 Message.obtain()方法来从线程池中获取一个Message对象,这样做的好处可以是消息对象反复利用,避免额外的开销,所以建议在得到Message对象的时候,建议采用.obtain()的方式 **

接下来就是这些发送消息方法最终调用的终极方法,如下图:

Handler机制源码分析之Handler_第6张图片
sendMessage00.png

我之前看源码时做的笔记应该是解释的比较清楚了的,可以看到最后调用了enqueueMessage方法,并且传了三个参数,一个MessageQueue的实例,一个Message对象,最后一个是消息的执行时间.而另一个方法就是将最后的参数值置为0.这个方法看名字就明白是将其添加到消息队列中,接下来就看看这个真 终极方法.
Handler机制源码分析之Handler_第7张图片
将Message加入进消息队列.png

这里之前好像看了忘记写注释了,然后又跑去源码里截了个图...(尴尬!)
可以看到,这里使用了 msg.target=this,this当然指的就是我们的Handler对象,它将this赋给了Message里 的target字段,由此可知target也就是一个Handler对象,为什么要这么用呢?** 因为在Looper里loop()方法中,也就是我们在发送消息后一定要写的Looper.loop()方法,大家都知道,这个方法是为了从消息队列里轮询取出消息,里面是一个死循环.那和这个有什么关系?因为其里面有个这样一个方法 msg.target.dispatchMessage(msg);可以看到里面使用Message里的target字段来调用diapatchMessage方法的,至这个方法就是一种处理消息的优先级,我们之后再讲. **

接下来就是发送Runnable对象,post方法

Handler机制源码分析之Handler_第8张图片
发送Runnable对象

可以看到,其内部是调用了send方法,send方法需要一个Message对象,也就是其 getPostMessage(r)必然返回一个Message对象.接下来,来看看这个方法.
Handler机制源码分析之Handler_第9张图片
将Runnable转化为Message.png

果然,就是把Runnable对象赋给Message中的callback字段而已.

4. Handler处理消息

上面提到过,消息最终执行是调用了msg.target.dispatchMessage(msg);这个方法,所以接下来就来看看这个方法的具体实现吧.

Handler机制源码分析之Handler_第10张图片
dispatchMessage.png

可以看到首先判断Message中callback字段是否有实例,有的话就执行 handleCallback(msg)这里面会调用 message.callback.run();,之后会判断是否实现了Handler中的内部接口Callback中的handleMessage方法,实现了就执行其方法,值得注意的是,这个方法返回一个boolean值.最后才是调用我们常用的Handler中的handlemessage方法,所以** 消息处理的优先级为: message.callback.run();> mCallback.handleMessage(msg)> handleMessage(msg) **

以上就是Handler机制里关于Handler发送消息和处理消息的相关部分了,其实里面还有很多其他的方法.比如

  • Handler内部还有一个MessageImpl的类继承IMessage.Stub.这个使Messenger可以通过handler来发送进程间的消息.毕竟两个进程间也是通过一个线程来互相发送消息的.
  • Handler也可以直接使用obtainMessage()来直接从消息池中获取一个Message对象
  • Handler中还有没有消息处理,进入wait和处理消息后notifyall的一套实现过程.
这里主要是梳理一下Handler执行流程的思路,具体的最好还是去看看源码,毕竟只有自己去做过的东西才能真正理解.在Handler类里面的还有其余的部分,有兴趣也可以去看看一下,Handler类的源码不多,也可以锻炼一下自己看源码的能力.
第一次发文,写的不是太好,有错误的地方,欢迎指出=-=.

相关文章:
Handler机制源码分析之Message
Handler机制源码分析之Looper

你可能感兴趣的:(Handler机制源码分析之Handler)