handler的内部基本上可以分为四部分
一 Message对象创建
handler.obtainMessage(),在底层是调用的Message.obtain方法,如果消息池中有Message对象,就直接调用,如果为空,才new Message()进行创建.
消息队列中的顺序是由消息本身维护的,消息队列中的消息是类似单链表的结构,每个消息对象都有一个next属性,指向下一个消息.
假设消息池中有三个消息 a.b.c 进入到obtain的方法中,首先判断sPool(是消息池里的第一条消息) 是否为空. 不为空,就赋值给Message对象, sPool = m.next; 把sPool指向b消息; sPoolSize-- 长度自减 return m ,这时消息队列中的消息就只剩下 b 和 c
二 Handler的创建
在new Handler的时候会直接拿到Looper对象(Looper.myLooper())和消息队列对象(mLooper.mQueue) Looper对象和消息队列对象都是直接获取的.这两个对象在应用启动的时候就已经创建好了
应用启动的时候,主线程(UI线程)会创建并启动,会调用创建Looper对象和消息队列对象的方法prepareMainLooper()
Looper可以不停的进行轮训,因为调用了Looper.loop()方法,其内部是一个while(true)的死循环,所有对主线程的更新都是在这个循环中执行的 主线程不会停止就是因为这个Looper类中的loop方法中的while循环
这里是主线程真正执行的地方
在循环中,不断的读取消息队列中的消息,
管道机制: 在管道中有一个特殊文件,其实就是一个共用内存,它有两个引用,一个读取,一个写入,子线程不断写入,主线程不断读取,完成信息的交互.
如果消息队列中没有数据,主线程会进入睡眠,当子线程写入数据时,主线程苏醒,读取数据, 唤醒主线程的是管道,而不是消息队列中的消息,当子线程往消息队列中写入消息后,还需要往管道中写入一个数据.唤醒主线程
三 消息的发送
消息发送的所有方法最终都回到了sendMessageAtTime(), 把消息插入到消息队列中.放入消息队列中都是依据一个时间参数找到位置的,
如果消息队列是空的,那么肯定是发送的消息肯定是第一条
如果when = 0 或者 when < p.when(第一条消息的时间) 那么这条发送的消息就插入到了第一条
否则,就要那msg.when和消息队列中的每条消息的when进行比较,选择msg的位置.
四 Looper处理消息
Message对象中有一个成员变量target,这个target是记录此消息对象是由谁创建的,
是在obtain方法中传入的this参数赋值的,也就是handler对象
就是说target是有那个handler创建的,那么消息就有那个handler负责处理. 因为可以有多个handler给同一个消息队列发送消息
一 Message对象创建
handler.obtainMessage(),在底层是调用的Message.obtain方法,如果消息池中有Message对象,就直接调用,如果为空,才new Message()进行创建.
消息队列中的顺序是由消息本身维护的,消息队列中的消息是类似单链表的结构,每个消息对象都有一个next属性,指向下一个消息.
假设消息池中有三个消息 a.b.c 进入到obtain的方法中,首先判断sPool(是消息池里的第一条消息) 是否为空. 不为空,就赋值给Message对象, sPool = m.next; 把sPool指向b消息; sPoolSize-- 长度自减 return m ,这时消息队列中的消息就只剩下 b 和 c
二 Handler的创建
在new Handler的时候会直接拿到Looper对象(Looper.myLooper())和消息队列对象(mLooper.mQueue) Looper对象和消息队列对象都是直接获取的.这两个对象在应用启动的时候就已经创建好了
应用启动的时候,主线程(UI线程)会创建并启动,会调用创建Looper对象和消息队列对象的方法prepareMainLooper()
Looper可以不停的进行轮训,因为调用了Looper.loop()方法,其内部是一个while(true)的死循环,所有对主线程的更新都是在这个循环中执行的 主线程不会停止就是因为这个Looper类中的loop方法中的while循环
这里是主线程真正执行的地方
在循环中,不断的读取消息队列中的消息,
管道机制: 在管道中有一个特殊文件,其实就是一个共用内存,它有两个引用,一个读取,一个写入,子线程不断写入,主线程不断读取,完成信息的交互.
如果消息队列中没有数据,主线程会进入睡眠,当子线程写入数据时,主线程苏醒,读取数据, 唤醒主线程的是管道,而不是消息队列中的消息,当子线程往消息队列中写入消息后,还需要往管道中写入一个数据.唤醒主线程
三 消息的发送
消息发送的所有方法最终都回到了sendMessageAtTime(), 把消息插入到消息队列中.放入消息队列中都是依据一个时间参数找到位置的,
如果消息队列是空的,那么肯定是发送的消息肯定是第一条
如果when = 0 或者 when < p.when(第一条消息的时间) 那么这条发送的消息就插入到了第一条
否则,就要那msg.when和消息队列中的每条消息的when进行比较,选择msg的位置.
四 Looper处理消息
Message对象中有一个成员变量target,这个target是记录此消息对象是由谁创建的,
是在obtain方法中传入的this参数赋值的,也就是handler对象
就是说target是有那个handler创建的,那么消息就有那个handler负责处理. 因为可以有多个handler给同一个消息队列发送消息