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

首先要介绍的是: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:取消息

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容