Android消息处理机制--Looper,Handler,Message

来源:互联网 发布:卖家2017淘宝客新玩法 编辑:程序博客网 时间:2024/05/01 02:30

ThreadLocal

ThreadLocal并不是线程,而是用于存放线程内部的局部变量,这个局部变量对每一个线程来说有属于该线程自己的值,所有的线程分享同一个ThreadLocal对象,但是访问该对象是却得到不同的变量值,并且被一个线程修改了值不会影响另一个线程的值。例如在Android的消息处理机制中ThreadLocal就存储了Looper对象。


Looper

Looper循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
Looper对象所在的线程是一个LooperThread(循环线程,可实现消息循环,这里用于循环处理消息队列),且其所在线程有且只有一个Looper对象;
普通的线程要想成为LooperThread可以在其run()方法中调用Looper的prepare()方法和loop()方法即可。
Looper的prepare()方法,用于初始化Looper和MessageQueue,将Looper对象设置为ThreadLocal对象
Looper的loop()方法用于循环处理Looper中的MessageQuene,不断的从MessageQuene中取出头部的消息
Looper的myLooper()方法用于得到当前线程的Looper对象,(Looper)sThreadLocal.get(),其实就是调用的ThreadLocal的get()方法,返回的就是Looper.
Looper的getThread()方法得到Looper对象所在的线程
Looper的quit()方法用于结束looper循环
Android的主线程也是一个LooperThread,因此默认的就有对应的Looper,消息队列等;这也是为什么我们习惯于在主线程创建Handler,后面的Handler会讲到
总结:LooperThread线程包含Looper(ThreadLocal),Looper(ThreadLocal)包含消息MessageQuene




Handler

1,Handler用于向MessageQuene中添加消息和处理消息(只能处理自己发送的消息),
2,Handler的post、sendMessage等发送消息的方法最终都是调用的同一个方法sendMessageAtTime(),将消息添加到MessageQueue
2,Handler创建时会关联一个Looper,默认的构造方法关联其创建时所在线程的Looper,且该线程必须是LooperThread,且关联该Looper的MessageQuene。这些从构造方法的原码中可以看到。
3,因为你可以根据需要多次new出Handler,所以一个LooperThread中可以有多个Handler,但是只能有一个Looper对象
4,Handler可以在任意线程发送消息到关联的MessageQuene中,但是只能在其关联的线程(LooperThread)中处理消息,这就是为什么为什么不能
在子线程更新UI的原因,因为我们习惯在主线程创建Handler,该Handler默认也就关联了主线程,因此此时该Handler只能在主线程接收到消息,虽然我们在
子线程发送的消息,但是在子线程却无法从MessageQuene中获取到该消息,因此无法更新UI。
所以不能绝对的说子线程不能更新UI,而是要看你要更新UI的线程和Handler是否是同一个线程
总结:LooperThread线程包含Looper(ThreadLocal)和多个Handler,Looper(ThreadLocal)包含消息MessageQuene


Meaage

1,Message是要发送的消息的载体
2,Message.obtain()用于从全局的消息池中获取一个消息实例,比直接new Message()节省资源,因为Message使用完后系统会调用recycle()方法回收,如果自己new很多Message,每次使用完后系统放入缓存池,会占用很多内存的。

0 0
原创粉丝点击