【Android】Handler相关的一些知识点

1. 为什么主线程不会因为Looper.loop()里的死循环卡死?

主线程确实是通过Looper.loop() 进入了 循环状态, 因为这样主线程才不会像我们一般创建的线程一样, 当可执行代码执行完后,线程生命周期就终止了。
在主线程的MessageQueue没有消息时, 便阻塞在MessageQueue.next() 中的nativePollOnce()方法里, 此时主线程会释放CPU资源进入休眠状态,直到新消息达到。所以主线程大多数时候都是处于休眠状态, 并不会消耗大量CPU资源。
这里采用的linux的epoll机制,是一种10多路复用机制,可以同时监控多个文件描述符,当某个文件描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作拿到最新的消息,进而唤醒等待的线程。

2. post 和sendMessage 两类发送消息的方法有什么区别?

post一 类的方法发送的是Runnable对象, 但是其最后还是会被封装成Message对象, 将Runnable对象赋值给Message对象中的callback变量, 然后交由sendMessageAtTime()方法发送出去。在处理消息时, 会在dispatchMessage() 方法里 首先被handleCallback(msg) 方法执行, 实际上就是执行Message对象里面的Runnable对象的run 方法。
而sendMessage – 类的方 法发送的直接是Message对象,处理消息时,在dispatchMessage里优先级会低于handleCallback(msg) 方法, 是通过自己重写的handleMessage(msg) 方 法执行。

3. 为什么要通过Message. obtain()方法获取Message对象?

obtain方法可以从全局消息池中得到一个空的Message对象, 这样可以有效节省系统资源。同时, 通过各种obtain重载方法还可以得到一些Message的拷贝, 或对Message对象进行一些初始化。

4. Handler 实现发送延迟消息的原理是什么?

我们常用postDelayed() 与sendMessageDelayed() 来发送延迟消息, 其实最终都是将延迟时间转为确定时间, 然后通过sendMessageAtTime() -> enqueueMessage -> queue. enqueueMessage这一系列方法将消息插入到MessageQueue中。所以并不是先延迟再发送消息,而是直接发送消息,再借助MessageQueue的设计来实现消息的延迟处理。
消息延迟处理的原理涉及MessageQueue的两个静态方法MessageQueue. next()和MessageQueue.enqueueMessage()。通过Native方法阻塞线程- -定时间, 等到消息的执行时间到后再取出消息执行。

5. 同步屏障SyncBarrier是什么?有什么作用?

在一般情况下,同步和异步消息处理起来没有什么不同。只有在设置了同步屏障后才会有差异。同步屏障从代码层面上看是一个Message对象,但是其target属性为null,用以区分普通消息。在MessageQueue.next()中如果当前消息是一个同步屏障,则跳过后面所有的同步消息,找到第一个异步消息来处理。但是开发者调用不了。在ViewRootlmp的U测绘流程有体现

6. IdleHandler 是什么?有什么作用?

当消息队列没有消息时调用或者如果队列中仍有待处理的消息, 但都未到执行时间时, 也会调用此方法。用以监听主线程空闲状态。

7. 为什么非静态类的Handler导致内存泄漏?如何解决?

首先, 非静态的内部类、匿名内部类、局部内部类都会隐式的持有其外部类的引用。也就是说在Activity 中创建的Handler会因此持有Activity 的引用。
当我们在主线程使用Handler的时候, Handler 会默认绑定这个线程的Looper对象, 并关联其MessageQueue, Handler发出的所有消息都会加入到这个MessageQueue中。Looper 对象的生命周期贯穿整个主线程的生命周期,所以当Looper对象中的MessageQueue里还有未处理完的Message时, 因为每个Message都持有Handler的引用, 所以Handler无法被回收, 自然其持有引用的外部类Activity也无法回收,造成泄漏。
使用静态内部类+弱引用的方式

8. 如何让在子线程中弹出toast?

调用Looper.prepare以及Looper.loop(), 但是切记线程任务执行完, 需要手动调用Looper.quitSafely()否则线程不会结束。

猜你喜欢

转载自blog.csdn.net/weixin_42473228/article/details/125869811