Android的Handler原理记录

1、线程和looper绑定?

使用Looper.prepare ,基于线程的ThreadLocal 在prepare时new Loop

2、如何保证一个线程只有一个looper?

一个线程就只有一个looper了,因为如果执行一遍线程运行 Looper.prepare() 后,线程中有looper了,再次执行这个方法,直接会抛异常,这样canLooper就会为false了,接下来往下走就不会执行Looper.loop()了。

3、Handler内存泄露原因?其他内部类为什么没有这个问题?

内部类虽然和外部类写在同一个文件中,但是编译后还是会生成不同的class文件,其中内部类的构造函数中会传入外部类的实例,然后就可以通过this$0访问外部类的成员。

第一种情况,是通过handler发送延迟消息,核心问题是主线间接引用到了activity没有释放,主线程 —> threadlocal —> Looper —> MessageQueue —> Message —> Handler —> Activity

第二种情况:由于子线程这个匿名内部类持有了外部类的引用,而子线程本身是一直在运行的,刚才说过运行中的线程是不会被回收的,所以这里内存泄漏的引用链应该是:运行中的子线程 —> Activity,当然,这里的Handler也是持有了Activity的引用的,但主要引起内存泄漏的原因还是在于子线程本身,就算子线程中不用Handler,而是调用Activity的其他变量或者方法还是会发生内存泄漏。

4、为啥主线程可以new Handler?其他子线程可以吗?

主线程已经创建了 Looper 对象并开启了消息循环,其他子线程可以,但必须Looper.pearer绑定loop

5、子线程维护的looper 没有消息是是怎么处理的?

queue.next()会一直等待,这个时候就会block住,换句话说,这里block住,意味着Lopper一直在这里面等待,run函数一直处于等待状态,run会一直被执行,线程不会销毁,结果内存泄漏,线程一直处于执行状态,所以这时候,我们线程所有的上下文全部都会在内存当中,那么这样自会导致CPU浪费,内存浪费
解决办法:
在Looper里面有一个quite(),会调用nativeWake,nativePollOnce是出于等待,nativeWake是唤醒,唤醒之后往下面执行,最后next返回null,loop循环就会退出,Looper就推出,run方法往下执行,接着就会释放内存,把CPU交出去,给别人用。

6、Looper的死循环为什么不会导致卡死?

  Looper的死循环就是为处理主线程的消息,主线程的呈现就是looper的结果

7、Handler 的postDelay后的消息队列怎么变化?

  • 1.消息是通过MessageQueen中的enqueueMessage()方法加入消息队列中的,并且它在放入中就进行好排序,链表头的延迟时间小,尾部延迟时间最大
  • 2.Looper.loop()通过MessageQueue中的next()去取消息
  • 3.next()中如果当前链表头部消息是延迟消息,则根据延迟时间进行消息队列会阻塞,不返回给Looper message,直到时间到了,返回给message
  • 4.如果在阻塞中有新的消息插入到链表头部则唤醒线程
  • 5.Looper将新消息交给回调给handler中的handleMessage后,继续调用MessageQueen的next()方法,如果刚刚的延迟消息还是时间未到,则计算时间继续阻塞

8、消息队列的消息由多个handler发送,怎么保证线程安全?

通过synchronized来保证了线程的安全性

9、MessageQueue的quit和quitSafely 的区别

removeAllFutureMessagesLocked是会等延时消息进行时间判断符合超时去删除
 removeAllMessagesLocked 直接清理message

  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值