Handler消息机制

来源:互联网 发布:制作身份证图片软件 编辑:程序博客网 时间:2024/05/23 11:29

需要的类

  • handler
  • message
  • messageQueue

存在意义

  1. 主线程不能做耗时操作,只能放在子线程
  2. 子线程不能修改主线程UI。

三者之间如何协作

浅显理解

  • 线程A需要对线程B的界面需要操作时,会先将需要操作的数据封装成Message对象
    • Message msg=handle.obtainMessage()
  • Message对象通过B线程创建的Handler对象的sendMessage方法保存到B线程的Looper对象的成员变量MessageQueue中

    • 主线程的Looer系统创建,子线程自己创建
    • Looper.loop()不断轮询MessageQueue
  • 当B线程的Loop的静态方法loop方法发现MessageQueue中的Message 对象后loop方法将其交给Handler对象的handleMessage方法处理

深入理解

  1. messageQueue
    • 链表形式存储Message对象
    • 创建Message对象handle.obtainMessage()b)实际是调用了Message.obtain(),将handler对象传递给Message对象的target成员变量,以便handler的loop()方法将Message传递给Handler的方法MessageQueue.
public static Message obtain(Handler handler){Message msg=obtain(); // 无参数 c)具体实现msg.target=handler;return msg}

c)Message.obtain()方法的

sPool !=null){  //判断消息池是否为空message msg=sPool; //消息池是链表sPool=msg.next; //链表头指针移动到下一位m.next==null;return msg;}return new Message(); 

2.Handler
a)一个线程创建handler对象的时候已经获取到该线程的 Looper,messageQueue,子线程在创建handler对象之前要先创建Loop

publicic Handler(){mLooper=Looper.myLooper();If(mLooper ==null){//抛异常}mQueue=mLooper.mQueue;}`

b)handler.sendMessage() 将message存放到MessageQueue中,按照执行时间与消息队列中的其他消息进行比对,将其插入MessageQueue适当的位置

3.Looper
a)Looper.prepare()
1.sThreadLocal(new Looper());//TheadLocal 线程单例 一个线程里只能创建一个Looper对象
b) new Looper()
public Looper(){
mMessageQueue=new MessageQueue();
}
c)主线程的Looper如何自动创建及运行
1.系统文件的ActivityThread.javad中的Main方法调用Looper中的perpareMainLooper()方法,perpareMainLooper调用Looper.perpare()方法
2.Main方法调用Looper的loop()方法不断轮询消息队列让主线程不会退出
d)Looper对象的loop()方法不断轮询消息队列当发现消息,调用创建该消息时(handle.obtainMessage)保存的handler对象的dispatchMessage,通过dispatchMessage调用未实现的方法handleMessage
public static void loop(){ //伪代码
for( ; ; ){ //死循环
((Handler)(sg.target)).dispathMessage(msg); //msg 轮询到的msg
}
}

注意
i.其他线程只要 要操作该线程UI就要给该线程创建Handler对象
ii.其他线程只要 要操作该线程UI就要给该线程创建Looper对象(主线程除外)
iii.Looper通过loop()方法不断轮询MessageQueue
iv.loop()方法将MessageQueue中Message拿出来交给Handler方法handleMessage
v.MessageQueue是Looper的成员变量
vi.Handler是线程间通讯的工具

0 0