Handler

1、Handler
a:在主线程中实例化Handler对象,并重写handleMessage方法,处理子线程发送过来的数据(通过Message对象传递消息)

b:在子线程中使用主线程中实例化的Handler对象,调用send**或post**方法向主线程发送消息,在发送之前,数据应先封装到Message中

c:Message,使用该类封装数据

整数:arg1,arg2
对象:obj
类型:what  通常使用常量
数据多:Bundle

写法1:每次都会创建新的Message对象,耗费资源,不建议使用
 Message msg = new Message();
msg.obj = bm;
handler.sendMessage(msg);

写法2:从消息池中获得Message对象
Message msg = Message.obtain();
msg.obj = bm;
handler.sendMessage(msg);

写法3:从消息池中获得Message对象,此Mesage对象与指定的Handler关联
Message msg = handler.obtainMessage();
msg.obj = bm;
msg.sendToTarget();

handler.sendMessage(msg);

写法4:
Message msg = Message.obtain();
msg.obj = bm;
msg.setTarget(handler);
msg.sendToTarget();


2、Handler涉及到的核心类
a:Handler,消息的处理者(消息的发送,消息的接收并处理),哪一个Handler发送的消息,就由该Handler的handleMessage方法来处理(Handler自己给自己发消息)

方法:
 sendMessage(msg):发送消息
 sendMessageDelayed(msg, 0):延迟多少毫秒之后发送消息
 sendMessageAtTime:在设置的某个时间发送消息,将消息存入消息队列中
 obtainMessage():从消息队列中取出消息
 handleMessage(): 处理消息
 post(Runnable):run()运行在主线程中,可以更新UI
 postDelayed():延迟多少毫秒调用run方法

属性:
 MessageQueue mQueue;
 Looper mLooper;

b:Message:传递的消息,封装了业务的数据。

方法:
 obtain():从消息池中取出消息对象,如果消息池中没有消息对象,则创建新的对象并返回;如果有,直接取出消息对象并返回
 sendToTarget():由target指定的Handler发送消息
 setTarget():将指定的Handler设置为属性target
 recycle:重置属性至最初状态,将Message对象存入消息池中

属性:
传递各种消息:
int arg1
int arg2
Object obj
int what
bundle data

Handler target:用来标记发送该消息的Handler
Message sPool:消息池中的头指针
int sPoolSize:消息池中存储消息的数量
final int MAX_POOL_SIZE = 50:最多存放的消息数量

c:Message Queue:消息队列,随着Looper的创建而创建,使用ThreadLocal与Looper建立关系,在一个线程中,只能有一个Looper和一个MessageQueue的实例,存放Handler发送的消息。

d:Looper:轮询器,循环体,在UI线程中,默认已经创建Looper,无需手动创建,循环读取消息队列中的消息。

属性:
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
 底层存储方式:创建Looper与线程关联
Map<Thread,Looper>

Looper sMainLooper:主线程中的Looper对象

MessageQueue mQueue:消息队列

方法:
prepare:创建Looper对象,存储到ThreadLocal中,与线程线程关联

loop():从MessageQueue中取出Message对象
 获得Looper对象
 获得Looper对象关联的MessageQueue
 循环遍历,从MessageQueue中取出Message
 msg.target.dispatchMessage(msg); Message对象通过发送它的handler对象,分发消息,交给自己的Handler对象处理

myLooper(): 取出与线程关联的Looper

 

3.Handler的原理

  在一个线程中调用Looper.prepare()方法来创建Looper,即将此线程升级为Looper Thread(循环线程),当Looper创建成功后,系统会自动创建MessageQueue,并与Looper进行绑定。

再调用Looper.loop()方法,启动Looper循环读取MesssageQueue中的Message,如果MessageQueue中没有Message,则会阻塞,当读取到Message时,会调用Message.target的dispatchMessage()方法将其分发给消息的处理者。

在此线程中,实例化Handler,在实例时,系统会根据线程本地变量查找Looper,如果Looper存在,则绑定Looper的MessageQueue,如果Looper不存在,则抛出异常(在创建Handler之前必须调用Looper.prepare()来创建Looper),注:实例化的Handler对象,需要暴露给其它线程(定义类成员)

在其它的线程中,调用暴露的Handler对象的send或post方法向Handler的MessageQueue发送Message。如果以post方式发送Runnable时,系统先会创建一个空的Message,并将Runnable作为Message的callback使用。
另外,send或post()方法内部已设置Message的处理者(target)为Handler本身。

因为Looper是循环读取MessageQueue中的Message,因此当Handler的send或post方法执行时,Looper就会把此Message读取到,并转发给Message的处理者(Message的发送者---即Handler本身)。在Handler的dispatchMessage()方法中处理Looper转发过来的Message时,会判断Message的Callback是否为空,如果不为空,则直接执行Runnable的run方法,如果为空,则调用Handler的handleMessage()方法处理Message。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值