Handler1 Looper
200 Words|Read in about 1 Min|本文总阅读量次
Handler是一个优秀的内存共享方案。其内存管理和设计思路相当完整。 通过Handler来通知UI组件更新或者是处理对应消息。那么具体Handler机制是什么?
Handler1 Looper
开篇问题
1.一个线程有几个handler
2.一个线程有几个looper,如何保证
3.Handler会出现内存泄漏问题吗,怎么解决内存泄漏
4.子线程总如何使用Handler
Handler整体流程
优先级队列
Handler流程图
Looper
ThreadLocal
ThreadLocalMap
1.looper。java中无限调用queue。next,会不会出现msg=null
messagequeue。java
nativePollOnce(),linux层休眠
一个线程有几个handler
一个,ui主线程中可以有activty,service,他们都可以使用UI主线程
一个线程有几个looper,如何保证
looper。java中prepare函数如果存在threadlocal那么会抛出异常不能new looper,所以一个threadlocal对应一个looper
handler内存泄漏原因
内部类持有外部类引用。this调用ondestory并不能释放,jvm认为当前this正在被handler使用,内部类没办法释放,this类也没办法释放
(其他内部类是不耗时的)
handler原理
其他的类不存在内存泄漏。
handler可以发送delay
handler中msg。target=this
messagequeue会持有message,msg中持有了一个handler,handler中持有了this,
怎么解决内存泄漏
软引用加static,百度
子线程创建handler如何解决?
主线程为什么可以new handler?
looper初始化prepare
其中activitythread。java中main函数Looper。prepareMainLooper(),Looper。loop()
子线程使用handler,looper必须prepare然后再Loop,才能使用handler
ams是以activitythread
子线程维护一个Looper,消息队列无消息的时候处理方案是什么,有什么作用
Looper。prepare,new handler,Looper.loop,Loop。quitSafely
在Looper。loop中有一个for(;;)死循环中Message msg=queue。next(),使得Looper一直阻塞不会退出
Looper里面有一个quitSafely()调用messagequeue quit函数中有mQuitting=true,removeAllFutureMessageLocked释放内存,nativeWake会通知Message next()函数中nativePollOnce(),让他取消阻塞执行下去。
其中,messagequeue这个类里面的Message next()里面也是死循环,一旦执行下去之后发现mQuiiting为true,return null
也就是Looper。loop中的死循环
if (msg == null) return;loop收到null直接返回
quitSafely作用,
1.释放内存,获取不到Looper。且让Looper退出
2.释放线程
主线程使用Loop。quitSafely,会抛出异常不让你调用
销毁的过程只是置零,并不会把东西一个一个移除
子线程-》主线程
保证不会出现队列的混乱,保证线程安全
涉及了多线程并发编程
1.安全性
Messagequeue里面的enqueueMessage放消息里面有synchronize
next取消息synchronize,保证取消息
2.handler delay消失时间准确吗?安全性
synchronize修饰一个方法,静态方法,代码块(object)和代码块(this)区别
我们使用message该怎么创建
obtain
内存共享,内存复用,内存抖动
享元设计模式
synchronize(spoolsync)
Message m=spool
Message属性会持有一个next,spool是消息队列的头,属于链表
使用handler delay消息队列会有什么变化
这个消息队列为空,不会立刻执行,计算等待时间
添加一个message,立刻在messagequeue里面的enquemessage函数nativeWake来唤醒Message next()函数中nativePollOnce(),接着出发Message next()函数中nextPollTimeoutMills变量的值,等下次next循环会在nativePollOnce中体现睡眠时间,wait
Looper死循环为什么不会导致应用卡死
主线程泡在Looper。loop
app都有一个虚拟机,都有一个main函数
(ams问题APP启动流程)launcher-》application-》zygote-》虚拟机-》ActivityThread
activity,service都有一个loop 以消息的方式存在
主线程唤醒的方式
1)输入事件2)往looper里面添加消息
ANR(屏幕按下)广播10秒内没有执行
主线程中Looper。loop next会休眠
类似微信banner,消息都会第二天通知,ui主线程休眠
应用卡死跟Looper是没有关系的,应用卡死是跟输入无响应有关
1.Looper。loop中的queue。next是在休眠,并不是卡死(ANR)
2.屏幕上的操作即为输入事件,输入完之后
msg。target。dispatchMessage