美文网首页Android开发
handler浅谈(磨砺营马剑威Android)

handler浅谈(磨砺营马剑威Android)

作者: 磨砺营IT | 来源:发表于2016-08-18 10:31 被阅读43次

首先要介绍的是:Message这个类:

Message有三个必要重要的成员变量

1:int what(记录消息的种类)

2:Handler target(记录是谁把Message发送出去的,以后就由谁处理)

3:long when(处理消息的时间)

4:Message next;(当前消息的下个消息)

小结Message成员变量next和when使得消息成为一条链的结构如下图

When决定消息的顺序

下面我们在子线程里面初始化一个Handler对象,并使用他。那么为什么要舍近求远的选择子线程呢?因为主线程默认对Handler做了很多操作,不便于查看,接下里我们通过handler的使用过程来讲解Handler:

1、Looper.prepare();

这个方法必须调用不然就会直接崩溃,并且要先于new Handler之前调用

开始很多人就会有疑问:我在使用Handler的时候并没有调用这个方法啊?为什么他必须要调用,不调用还会报错?这里需要解释的是:一般的人都是在主线程中使用Handler,在主线程中其实也是调用的类似的方法的,接下来我们找到主线程中调用prepare()如下:

ActivityThread.java中的main方法:

public staticfinal void main(String[] args) {

//系统调用Looper.prepare()方法

Looper.prepareMainLooper();

//开启ActivityThread线程,即当前Android应用主线程

ActivityThread thread = new ActivityThread();

thread.attach(false);

//主线程Wile(true)?分发消息

Looper.loop();

所以说,在使用Handler之间肯定是要调用prepare这个方法的。那么调用这个方法做了什么操作呢?

new了一个looper对象然后调用了Looper的私有构造函数:

private Looper(boolean quitAllowed) {

mQueue = new MessageQueue(quitAllowed);

mRun = true;

mThread = Thread.currentThread();

}

在构造函数当中,待建了一个MessageQueue对象,将该对象设置给threadLocal通过threadLocal,给当前的线程,绑定了一个looper对象

小结:

1在一个线程当中,Looper.prepare()只能调一次,调用二次会抛异常。

2在主线程当中,此方法由系统调用,我们不用去调,详细代码可见:ActivityThead.java中的main方法

2、创建handler,使用handler发送消息。

Handler的构造函数当中主要干了二件事:

获得当前线程绑定的looper对象

mLooper = Looper.myLooper();

获得looper对象的messageQueue的引用

mQueue = mLooper.mQueue;

小结:其实这个地方和第一步创建Handler对象是一个相反的过程

handler发送信息:所有发送信息的方法,最终还是调用sendMessageAtTime(msg ,when)

在sendMessageAtTime方法中:msg.target

= this; // this就是当前handler,记录谁把消息发送到消息队列里面的,以后就会调用这个Handler把自己发送出去

queue.enqueueMessage(msg, uptimeMillis);

//

queue是MessageQueue如图

首先如果消息队列里面没有消息,或者消息的when小于第一条消息那么,加入的这条消息就会添加到消息队列的第一条,如果消息队列里面存在消息而且消息的when不小于第一条消息,那个这个时候,代码就会进入else里面,这个时候做的第一件事就是声明一个临时变量,然后进入到for(;;){}这个循环体。这个循环体其实就等价于while(true);接下来就是比较消息的when的大小了。然后给消息找到一个合适的位置,并插入。

小结:对象,enqueueMessage()方法,当前message ,加入到消息对列当中

MessageQueue中的代码:

enqueueMessage方法

这个方法将消息加入到消息对列中,在加入之前会通过每个消息的时间进行比较,然后把消息插入到相应的位置,他定义个临时变量

结论:

在MessageQueue当中,所有的message都是以单链的形式保存的,而且按时间从小到大的顺序保存取消息的方法(next())从messageQueue当中取出下一个应该执行的message,如果时间未到,就等待。

3、Looper.loop();

publicstatic void loop() {

final Looper me = myLooper();

final MessageQueue queue = me.mQueue;

for (;;) {//相当于while(true)死循环

//从messageQueue当中取出下一个应该执行的message如果时间未到,就等着

Message msg = queue.next(); // might block

//调用message对应的handler中的dispatchMessage方法,最终执行handleMessage方法

msg.target.dispatchMessage(msg);

}

}

总结:Handler机制里面其实包括了相关的类很多几个比较重要的类如:Handler、Message、Thread、MessageQuen、Loop。

Handler:发送消息和处理消息

Message:消息的信息的载体,记录被处理的时间和由谁处理

Thread:通过ThreadLocal记录每一个线程的MessageQuen

MessageQuen:存放消息的地方

Loop:取消息

相关文章

网友评论

    本文标题:handler浅谈(磨砺营马剑威Android)

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