面试准备——Handler原理

作者: So_ProbuING | 来源:发表于2021-04-12 11:38 被阅读0次

我们在Android中,从sendMessage到Handler中的handleMessage中间到底发生了什么?


handler

Hanlder中的主要函数

Handler中的主要函数

可以看到无论怎么操作Message最后都会调用handler的enqueueMessage方法
然后在handler的enqueueMessage方法中又调用了messageQueue.enqueueMessage
enqueueMessage就是向MessageQueue中添加消息

handlerMessage如何调度?

在MessageQueue中有一个next()函数,这个函数负责从消息队列里面取出消息,取出消息后调用dispatcher分发消息,然后使用handleMessage来处理消息

会从消息队列的头部取消息,如果取出的消息还没到执行的时间就会等待

MessageQueue中的next()函数由谁来调用

MessageQueue中的取出Message消息是由Looper.loop()函数来调用 无限调用next()

消息队列:按照时间优先级顺序排队的单链表

一个线程可以有几个Handler?

一个线程可以有多个Handler,我们可以创建多个Handler,因为Handler是执行在主线程的,所以说一个线程可以有多个Handler

一个线程可以有几个looper?

一个线程只有一个looper,因为Looper的prepare()函数创建的,创建的时候会使用一个ThreadLocal来存储这个looper,而ThreadLocal中的Set方法是以key value形式存放线程的,而在ThreadLocal中只有一个value,并且在set中取了当前线程当作value 所以在Looper中ThreadLocal只有一个地方存储了Looper,并且在获取looper如果不为空会报错。

Handler内存泄漏的原因?为什么其他类没有这个问题?

Handler内存泄漏的原因一般是内部类持有外部类的引用,生命周期不一致,内部类中默认会有外部类的引用。内存泄漏和Handler的原理有关系,因为Handler可以发送delay消息,而消息又要放到消息队列中,所以delay的消息会放在Message消息队列中,而在发送消息的时候会将Handler赋值给target,在enqueueMessage中会让Message持有Handler对象,Handler对象又持有外部类的this,所以Message在没有处理完之前会一直储存在内存中,所以需要等到Message处理完后才能销毁 而Message持有Handler 所以外部Activity destory()时候 由于有Message存在 Message又有Handler Handler又有Activity的this 所以会造成内存泄漏。
这个问题该怎么解决?软引用+static

为何主线程可以new Handler?如果想要在子线程中new Handler需要做什么准备?

因为在ActivityThread中main中已经执行过loop.prepare loop.loop,所以就是在最早执行的main函数中已经初始化了looper 所以主线程可以直接new Handler。在子线程中必须先prepare()初始化 然后再loop(),执行完成后要执行quit()

子线程中维护的Looper,消息队列无消息的时候的处理方案是什么?有什么用?

调用looper.quitSafty()函数,这个函数调用之后会清空所有的消息,回收message,释放内存,然后结束loop()方法,以节省性能

MessageQueue如何保证各线程添加数据并且线程是安全的

使用synchronized:加锁保证安全性

我们使用Message时应该如何创建它?

使用Message的Obtain方法

Looper死循环为什么不会导致应用卡死?

  1. 主线程的所有代码都是跑在looper.loop里面的

相关文章

网友评论

    本文标题:面试准备——Handler原理

    本文链接:https://www.haomeiwen.com/subject/zfqwkltx.html