Android Handler

1. 概念

handler通过发送和处理Message和Runnable对象来关联向对应线程的MessageQueue。

  1. 可以让对应的Message和Runnable在未来的某个时间点进行相应的操作;
  2. 让自己想要处理的耗时操作放在子线程,让更新UI的操作放在主线程。

2. 作用

当我们需要在子线程处理耗时的操作(例如访问网络,数据库的操作),而当耗时的操作完成后,需要更新UI,这就需要使用Handler来处理,因为子线程不能做更新UI的操作。

Handler能帮我们很容易的把任务(在子线程处理)切换回它所在的线程。简单理解,Handler就是解决线程和线程之间的通信的。

3. 分析

Looper
每一个线程只有一个Looper,每个线程在初始化Looper之后,Looper会维护好该线程的消息队列,用来存放Handler发送的Message,并处理出队的Message。它的特点是它跟它的线程是绑定的,处理消息也是在Looper所在的线程去处理,所以当我们在主线程创建Handler时,它就会跟主线程唯一的Looper绑定,从而当我们使用Handler在子线程发消息时,最终是在主线程处理,达到了异步的效果。

ActivityThread默认会把Looper初始化好,prepare以后,当前线程就会变成一个Looper线程。

MessageQueue
MessageQueue是一个消息队列,用来存放Handler发送的消息。每个线程最多只有一个MessageQueue。MessageQueue通常都是由Looper来管理,而主线程创建时,会创建一个默认的Looper对象,而Looper对象的创建,将自动创建一个MessageQueue。

Message
消息对象,就是MessageQueue里面存放的对象,一个MessageQueue可以包括多个Message。当我们需要发送一个Message时,我们一般不建议使用new Message()的形式来创建,更推荐使用Message.obtain()来获取Message实例,因为在Message类里面定义了一个消息池,当消息池里存在未使用的消息时,便返回,如果没有未使用的消息,则通过new的方式创建返回,所以使用Message.obtain()的方式来获取实例可以大大减少大量Message对象所产生的垃圾回收问题。

当我们调用handler.sendMessage(msg)方法发送一个Message时,实际上这个Message是发送到与当前线程绑定的一个MessageQueue中,然后与当前线程绑定的Looper将会不断的从MessageQueue中取出新的Message,调用msg.target.dispathMessage(msg)方法将消息分发到与Message绑定的handler.handleMessage()方法中。

一个Thread对应多个Handler,一个Thread对应一个Looper和MessageQueue,Handler与Thread共享Looper和MessageQueue。 Message只是消息的载体,将会被发送到与线程绑定的唯一的MessageQueue中,并且被与线程绑定的唯一的Looper分发,被与其自身绑定的Handler消费。

4. 特点

Handler使用的生产消费者设计模式:

  • 低耦合
    为什么不直接让消费者调用生产者的某个方法?如果这样直接调用必然会产生相互依赖的情况也就是耦合,如果以后生产者和消费者某一方变化都有可能会影响到对方,但是如果二者直接不直接依赖而是通过缓冲区来交互,这样耦合性就大大减低了。

  • 支持并发
    生产者可以放心的产生数据直接扔给消息缓冲区,而不用等待消费者那边是否已经处理完了消息,而导致生产者等待状态(生产者消息堵塞),这样就可以不用依赖消费者的处理速度了,互相独立。

  • 自由发挥
    这种模式还有一好处就是,如果生产者生产的数据速度过快,而消费者那边处理的比较慢,那么这个时候消息都会存在于缓冲区。这样生产者就能慢慢的消费这些数据了,所以定为自由发挥。

5. Handler引发的内存泄漏

原因: 静态内部类持有外部类的匿名引用,导致外部Activity无法释放

解决办法:

  1. handler内部持有外部activity的弱引用;
  2. handler改为静态内部类;
  3. handler.removeCallback()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值