Handler消息传递机制

1、Handler类方法:

handleMessage(Message msg):处理消息的方法,该方法通常被重写

HasMessage(int what):检查消息队列重是否包含what属性为指定值的消息

HasMessage(int what,Object):检查消息队列重是否包含what属性为指定值且object属性为制定对象的消息

多个重载的Message obtainMessage()获取消息

sendEmptyMessage(int what): 发送空消息

sendEmptyMessageDelayed(int what,long delayMillis): 指定多少毫秒之后发送空消息。

sendMessage(int what,long delayMillis): 立即发送消息。

sendMessageDelayed(int what,long delayMillis): 指定多少毫秒之后发送消息。 

可借助上面的这些方法,方便地利用Handler来进行消息传递。

2、工作原理

Message:Handler接收和处理消息对象;

Looper:每个线程只能拥有一个Looper,它的loop()方法负责读取MessageQueue中的消息,读到消息之后就把消息交给Handler进行处理。

MessageQueue:消息队列,它采用先进先出的方式。程序创建Looper对象时,会在它的构造里面创建MessageQueue对象。即:Looper和MessageQueue是唯一且关联的。

Handler:使用Handler发送消息,由Handler发送的消息必须被送到指定的MessageQueue,也就是说,如果希望Handler正常工作,必须在当前的线程中有一个MessageQueue,否则消息就没法保存。

不过MessageQueue是由Looper负责管理,也就是说,如果希望Handler正常工作,必须在当前线程中有一个Looper对象。为了保证当前线程中又Looper对象,可以分为2个情况讨论:

(1)在主Ui线程,系统已经初始化了一个Looper对象。因此程序可以直接创建Handler即可,然后就可以通过Handler来发送、处理消息。

(2)程序员自己启动一个子线程,必须自己创建一个Looper对应,并启动它。创建Looper对应调用prepare()方法。、

3、总结下

(1)Looper:每一个线程只有一个Looper,负责管理MessageQueue,会不断地从MessageQueue中取出消息,并将消息分给对应的Handler处理。

(2)MessageQueue:由Looper负责管理。

(3)Handler:它能把消息送到Looper管理的MessageQueue,并负责处理Looper分为它的消息。

Handler机制就是Android用于规范线程内或者线程间发送消息、然后分发消息、处理消息的一套规则,而消息就是一种信号,它可以通知我们去完成某项任务。在handler机制下,我们将需要在该线程下完成的任务信号(消息)放到该线程的消息队列中进行排队等待处理,然后交由处理者在该线程的环境下执行具体任务。当然这里的排队是按照某种条件进行的,那么当我们需要加急处理的时候也是会有方法进行处理的。
然后打一个不太好的比喻:handler机制就好比我们寄快递,在哪寄、寄什么、寄去哪里由我们自己决定,当我们将包裹交给快递公司后,快递公司就会将你的包裹经过分拣,交给专门负责你目的地的部门,通过运输最终送到目的地,当然到达目的地后,怎么处理快递由我们自己决定。在这个过程中,我可能说我这个快递很急,不能等其它在我之前寄的快递送完再送,那么我们就可以加急,直接先处理我们的快递。

4、针对在子线程中使用Handler的步骤:

子线程中:

(1)调用Looper的prepare()方法为当前的线程创建Looper对象,创建Looper对象时,它的构造器会创建创建与之搭配的MessageQueue

(2)有了Looper之后,创建Handler的实例,重写handleMessage()方法,该方法负责处理来自其他线程的消息。

(3)调用Looper的loop()方法启动looper。

UI主线程中:

(4)创建Message消息,并调用sendMessage发送消息。

Handler+Message异步消息处理机制_冰之沁泠的博客-CSDN博客

轻松掌握Android Handler消息机制核心代码 - 知乎

 5、实战

(1)释义

msg.object 用来放对象;(可以是任何类型)

msg.what :只能用来放数字,用在if、switch语句中。

(2)Message的2中后去方法:

第一种:

Message msg = new Message(),这种方法是new一个message,需要开辟内存空间

第二种:

Message msg =  handle.obtainMessage() ,这种方法是从消息池中拿到msg,不需要new一个。这种Message msg可以复用,性能消耗相对较少。当然消息池中如果没有msg,则会创建一个msg。

(3)例子:

Message msg = handler.obtainMessage();
		msg.arg1 = 1;
		msg.arg2 = 2;
		msg.what = 3;
		msg.obj = Object;

在Handler中接收
Handler handler = new Handler(){

    			@Override
    			public void handleMessage(Message msg) {
        				super.handleMessage(msg);
        //接收Message发送的消息  msg.what   msg.arg1  msg.arg2  msg.obj
        //这里msg.obj需要强转成你传过来的数据类型
}

(4)handler.obtainMessage()

handler.obtainMessage() 的作用是从当前的Handler中获取指定的Message以供再次使用

尤其是在监测线程中 如果不断的new Message() 可能出现错误 (错误信息已经忘了 没有记录 =.=)

有5个重载的方法

    public final Message obtainMessage ()
    public final Message obtainMessage (int what)
    public final Message obtainMessage (int what, Object obj)
    public final Message obtainMessage (int what, int arg1, int arg2)
    public final Message obtainMessage (int what, int arg1, int arg2, Object obj)
 

(5) sendMessage()例子

        Message msg = new Message();
        msg.what = MESSAGE_AUDIO_FOUCS_UPDATE;
        msg.obj = pkgName;
        mHandler.sendMessage(msg);

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
评论

打赏作者

学如逆水行舟,不进则退3038

你的鼓励是我最大的动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值