Handler

a.  

1.handler源码架构解析

2.一个线程有几个looper?如何保证

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

4为什么主线程可以new Handler?其它子线程可以吗?怎么做?

5.子线程中维护的Looper在消息队列无消息的时候处理方案是怎样的?

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

7.使用Handler的PostDelay后消息队列会有什么变化?

b. 

handler

looper

message

messageQueue:优先级队列(链表):按时间排序的队列

Thread 去调用Looper.loop (死循环for(;;))作为动力

c.

sendMessage()...||postMessage()....

--->sendMessageAtTime()

--->MessageQueue.enqueueMessage()

Looper.loop

--->msg=MessageQueue.next() --->if(msg==null)退出死循环(动力停止)

--->msg.target.dispatchMessage(msg)

--->Handler.handleMessage(msg)

1. 一个线程有几个Handler 

多个

2.一个线程有几个Looper,如何保证(涉及线程安全,并发编程)

threadLocal(线程隔离)为final唯一

<key,value>Map

每个Thread都对应一个ThreadLocalMap,这个map.set<key,value>,key是当前这个ThreadLocal,value是一个Looper。用这种方式将ThreadLocal和Looper唯一绑定

3. Handler 内存泄露的原因:持有activity

匿名内部类

内部类特征:持有外部类的对象

Handler 内存泄露,为什么其他内部类没有类似问题。

Handler的处理流程 

enqueueMessage()方法里将message.target=this(Handler)。target将在消息发送前(尤其是delay)一直持有这个Handler,而这个Handler一直持有外部类对象,所以造成内存泄漏。

解决办法:静态内部类不会持有外部对象。或者弱引用

4.为什么在主线程可以new Handler,如果需要在子线程new Handler,需要做什么。

launcher--->zygote--->application(Dalvik/Art虚拟机)--->ActivityThread.Main函数--->Looper.prepareMainLooper()&Loop.loop()

需要在子线程new Handler,需要做:Looper.prepare()&Loop.loop();

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

nativePollOnce--->linux--->epoll--->messageQueue

handler的睡眠和唤醒机制

主线程需要释放吗?(Looper.quit())为什么?

AMS(activityManagerSeivice) 通过Handler去管理;

四大组件的底层Binder

retrofit:@multipart @body(注解+动态代理+反射+okhttp)

6.既然可以存在多个handler往messageQueue中添加消息,发送消息时,各个handler可能处于不同线程中,那他内部如何确保线程安全。

一个线程-->一个Looper-->一个MessageQueue(final)

synchronized(this) :内置锁this代表messageQueque (并发编程)

7. 使用Message时,怎么创建?

享元设计模式:obtain 每次获取从队列中获取,每次用完后不直接将message==null,而是把message的成员变量置空,然后将message对象放入队列中,重复使用。

JVM:

new 分配一块内存 然后 destory  造成内存抖动 甚至OOM;

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

综合性问题:AMS和Handler源码,多线程

ANR:应用卡死的原因

a. 5s之内没有响应输入的事件,比如按键,屏幕触摸。(UI消息没有及时处理)

b. 广播接受器在10s内没有执行完。

AMS管理机制:

每一个应用都存在于自己的虚拟机中,也就是说每一个应用都有自己的一个Main函数。

启动流程:launcher--->zygote--->application(Dalvik/Art虚拟机)--->ActivityThread--->Main函数

所有应用所有生命周期的函数(包括Activity,service的所有生命周期)都运行在这个Looper里面,他们都是以消息的形式存在。

为什么主线程Looper休眠很长时间也不会出现ANR?(Looper中没有消息时会阻塞)

anr的主要原因是,message队列里面有消息(ui响应时间)需要处理,但没及时处理,比如前一条消息耗时超过5s,造成队列阻塞,后面消息也处理不了,卡死了。与Looper的睡眠没有任何关系。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三门峡的皮皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值