Handler 消息机制源码分析(三)

一、非主线程中使用Handler

先官方一段话
在这里插入图片描述
Looper.prepare:会创建一个looper 一个MessageQueue 一个NatvieMessage 一个 fd文件描述符
Looper.loop:开启自己的循环读取消息

二、Looper中的IO复用

一个 MessageQueue 对应一个mPtr

1.我们Android中可以创建多个MessageQueue 所需需要用IO复用

Looper中的 MessageQueue N个Handler 发送Message(阻塞在 IO复用中)同一个文件
其他线程中的 MessageQueue N个Handler 发送Message(阻塞在IO复用中)同一个文件

用Java 方式表述 Map<mPtr,List> (Message消息里面是有Handler)
Message就阻塞在这个 mPtr 中 直到mPtr被唤醒

mPtr 就是NativeMessage 对比(反射获取mPtr)
Main Looper mPtr = 124917845465360
Thread 1 Looper mPtr = 124917845462880
Thread 2 Looper mPtr = 124917845409920

三、常见面试问题

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

为什么Looper死循环不会导致应用卡死?epoll机制:
IO多路复用的一个实现;IO多路复用:在一个操作里同时监听多个输入输出源;

MessageQueue优先级队列 是如何进行排序的

优先级排序,就是依靠msg对象中提供的when参数,根据时间来进行排序;

Message(单链表结构)

单链表结构:非线性,非顺序的物理结构,由n个节点组成;
链表是采用“见缝插针”的存储方式,不要求内存连续,靠next指针关联;
存储的时候是随机存储;访问的时候是顺序访问;

如何创建Message对象;

Message对象可以通过new关键字,也可以通过obtain方法进行创建;
为什么选用obtain方法呢?
android app中会有大量需要通过handler发送消息,会发送大量的message对象;
为了避免频繁的创建和销毁message对象所造成的性能消耗,所以使用“缓存池”。

一个线程又几个Handler?怎么保证的?

多个,同步锁;

为什么主线程可以new handler,子线程中new handler怎么做?

因为主线程系统帮我们调用了looper,子线程中,可以通过自己调用Looper.prepare进行处理;

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

应该调用Looper的quit方法,因为可以将looper中的messageQueue里的msg都移除掉,并且将内存释放;

MessageQueue怎么保证内部线程安全

因为同步关键字

Handler源码的三条主线

handler的请求发送到哪里去了?

handler请求全部都发送到MessageQueue中,并且被保存在单链表(Message)中;

handler的请求怎么处理的?

在ActivityThread中,通过Looper.loop()方法不停从MessageQueue中获取Message对象,并调用Message对象中的target(指得就是handler)的dispatchMessage方法;

Handler,Looper,MessageQueue,Message关系是怎么样的,什么时候创建的?

Handler:MainActivity;
Looper:ActivityThread的main方法中(Looper.pareMainLooper),在创建Looper的同时,也会创建MessageQueue对象;

ThreadLocal

ThreadLocal为解决多线程程序的并发问题设计出来的;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值