handler机制
来源:互联网 发布:ap100编程教程 编辑:程序博客网 时间:2024/06/08 02:08
handler消息框架
1.Looper是消息循环类,负责从消息队列取消息,然后通过handler转发给UI线程,它包含mQueue成员变量,mQueue是一个消息队列MessageQueue。
2.MessageQueue是消息队列类,它包含了mMessages成员;mMessages是消息Message的实例。MessageQueue提供了next()方法来获取消息队列的下一则消息。
3.Message是一个消息结构体。包含next,next是一个Message实例,可以看出Message其实是一个链表。包含target成员,target是Handler实例。此外,它还包括了arg1,arg2,what,obj等参数,它们都是用于记录消息的相关内容。
4.Handler是消息句柄类。Handler提供了sendMessage()来向消息队列发送消息; 此外,Handler还提供了handleMessage()来由子类处理消息队列的消息;这样,用户通过覆盖handleMessage()就能处理相应的消息。
消息机制位于Java层的框架主要就有上面4个类所组成。在C++层,比较重要的是NativeMessageQueue和Loop这两个类。
模拟handler消息机制
1.编写Message类:
这类为了简便,很多方法不去实现,只是简单的模拟通信机制,具体细节可以取查看官方handler源码。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
只是一个简单的javaBean,没有实现单链表,没什么好解释的。
MessageQueue类:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
这类MessageQueue内部使用数组来模拟消息队列,定义一个mItems数组存放消息,源码使用的是链表。两个重要的方法:入队enqueueMessage();出队 next()。
Looper类:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
mQueue:消息的队列,在Looper初始化的时候创建这个队列,在loop方法中不断的从队列中取消息,然后把消交给handler
- 1
- 2
- 3
- 1
- 2
- 3
prepare方法。给ThreadLoacl设置Looper值,这样保证每个现场访问的Looper都是私有的Looper备份
- 1
- 1
myLooper方法。从sThreadLocal中取得私有的Looper变量
loop方法。 轮询消息队列
Handler类:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
handler也很简单,持有Looper,MessageQuene,通过sendMessage方法不断的给MessageQuene中添加消息,同时把handler对象绑定到Message上,方便消息处理完成后分发消息。
dispatchMessage方法分发消息,调用了handleMessage方法,这个方法大家都很熟悉,没有实现,交给子类重写,在这里处理消息。
整个handler处理流程都写完了,来看看整个流程的时序图(懒的画,网上找了张,感谢【hnust_癫狂】共享)
首先生成Message,丢给Handler,通过sendMessage()方法将Message发送到消息队列MessageQueue中去;还有一点需要说明的是,轮询器Looper是一直在轮询状态的,一直对消息队列MessageQueue进行轮询,如果一旦发现有Message,将Message返回;然后通过Message中Target拿到Handler对象,进行调用dispatchMessage() 将Looper拿到的message分发出去,最后Handler拿到消息,执行handlerMessage()方法。
上面遗留了一个很核心的问题—–消息队列是怎样处理这些消息的?
接下来通过生产者/消费者模型来实现消息队列,这也是handler跨线程的核心部分
要实现生产者/消费者模型,首先的有锁,这里使用ReentrantLock
主要考虑的重写入,它可以根据设定的变量来唤醒不同类型的锁,也就是说当我们队列有数据时,我们需要唤醒read锁;当队列有空间时,我们需要唤醒写锁。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
自己手写一次handler消息处理机制,再回过头来看看handler是不是很简单了,再也不怕面试中被问到。当然Android源码中的handler处理机制移值到C层处理了,我们不管它在c层还是java层,原理都是一致的,有兴趣可以去翻翻c层的源码。
实例代码下载:https://github.com/honjane/handlerDemo
- Handler机制
- Handler机制
- handler机制
- handler机制
- Handler机制
- Handler机制
- handler机制
- Handler机制
- handler机制
- Handler机制
- handler机制
- Handler机制
- Handler机制
- Handler机制
- handler机制
- handler机制
- Handler机制
- Handler机制
- spring对象加载过程测试
- C#基础
- Java通过Socket实现TCP编程
- spark 2.1 DiskBlockObjectWriter
- Linux中profile、bashrc、~/.bash_profile、~/.bashrc、~/.bash_profile之间的区别和联系以及执行顺序
- handler机制
- 我我我我问无无
- 极光推送集成
- Caffe三方库相关资料、编译方法和注意事项[补坑中]
- c#向MFC窗体发送消息
- Solr学习总结(四)索引配置schema.xml & solrconfig.xml
- centOS7中将Python2.7.5 升级到Python3.5.2
- Mac下命令行安装指定版本的lua,然后c++,lua相互交互
- 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?