Handler

一个线程如何保证只有一个Loop?

tip(什么是threadlocal? 是一块线程的内部的存储类,可以指定线程内存数据。这块数据只能线程内使用 )实际是它的静态内部类ThreadLocalMap为每个Thread维护了一个数组 下标是ThreadLocal分配的  value存储对应的值。为了保证只有一个值,则需要判断这个map对应key的vaalue是否为空,空就不设置。

Loop的构造器是private的,通过Loop里面的prepare方法初始化的。prepare方法里用到了threadlocal判断是否是空如果是空才setlooperf否则不设置这样保持只有一个loop。Thread ==》threadlocalmap(存储空间<唯一的threadlocal,value就是loop>==》这个流程保证了一个线程只有一个Loop。同时也创建了一个messagequeue.

一个线程有几个Handler?

可以随便new,但是只有一个loop和messagequeue

Handler为什么会出现内存泄漏?

内部类持有外部类的应用   我们将消息 发送,入队列中。masg 持有 handler   handler 持有 activity  。消息在队列中有延时activity销毁会出现内存泄漏。

如果handler为内部类(非静态内部类),那么会持有外部类的实例 若在handler.sendMessage的时候,activity finish掉了,那么此时activity将无法得到释放

如果申明handler为静态内部类,则不会含有外部类的引用, 但是需要在handler中更新UI(注意此时handler为static),则需要引入一个activity引用, 显然必须是弱引用,否则会导致和上面一样的结果

使用activity弱引用 之所以使用弱引用,是因为handler为static,使用activity的弱引用来访问activity对象内的成员

主线程没消息的时候怎么处理?子线程呢?

主线程会一直循环 ,因为Loop是我们ActivityThread 创建的不用管理关闭方法
消息睡眠和唤醒机制

生产者-消费者设计模式:

多线程: 10个事件,11

两个方面的阻塞?

1) message 不到时间 ,自动唤醒

2)  messageQueue为空,无限等待直到添加消息唤醒

子线程调用 quit: 唤醒线程-》 messagequeue -》null -》 退出loop

既然可以多个Handler往MessageQueue中添加数据(发送消息的handler可能处于不同线程)那么它内部是如何确保线程安全的?

锁   synchronized:内置锁  可重入锁 外部锁

messagequeue 的 添加 enqueue  和 next 取出  和退出 quit 被锁,对象里面的所有的函数,代码块,都会受限

锁:面试,锁

类 对象

MessageQueue 111= new messagequeue();

111. enqueueMessage

MessageQueue 222= new messagequeue();

222.enqueueMessage

222.next(222对象被锁只有调用完之后才能使用)

1个线程只有一个可以操作MessageQueue 的地方

线程池是如何实现先进先出的?

先进通过排序算法 插入维护时间先后顺序 ,然后从最前面取出

Handler运行流程?


子线程

handler-》sendMessage  -> messasgeQueue.enqueueMessage  //消息队列队列的插入节点(是一个容器相当于内存不是属于哪个线程)


looper.loop()->  messasgeQueue.next()-》handler.dispatchMessage()->handler.handleMessage()

主线程

Message,在动的过程,内存

new Messaage() obtain()

我们使用Message是如何创建的?

message 从队列中取出后没有销毁,而是将里面的参数都制空放到messagepoll里面,方便以后使用。避免频繁创造对象导致内存抖动。也叫享元设计  内存复用

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

Anr:5s内没处理玩  Activity Msg ——》5s——》handler---------》发消息anr提醒

而msg block 没消息处理 休眠 线程没事做放出Cpu

什么是消息的同步屏故障?


消息是根据执行时间进行先后排序,然后消息是保存在队列中,因而消息只能从队列的队头取出来。​那么问题来了!​需要紧急处理的消息怎么办

异步消息:刷新UI16ms左右 刷新UI:否则闪屏

异步消息: 立刻执行 messageQueue.postSyncBarrier() -》立刻执行,不能等别的消息  最后remove

在循环去消息的时候,判断targt==null  满足说明有同步消息

同步:正常消息

如何在子线程收消息 在主线程发消息?

HandlerThread 实现Loop.prepare  和loop.loop   有个GetLoop方法获取到loop 并且线程安全

解决这个有可能得异步问题

面试: 多线程得锁

wait();会释放synchronized锁

 synchronized()

nofityall() 不会释放sychronized  会唤醒wait

最简单得: okhttp glide,


IntentService

应用:

service:? 处理后台耗时任务

new Thread

service 后台

handler源码?源码有什么用

处理完》 service 自动停止:内存释放

同一个线程-》1 2 3 4  都执行完才算成功: 对线程的控制么 可以用多个线程来处理,一个线程处理完——————》下一个 ——》下一个

IntentSevice就可以完成这个工作 而且能够很好地管理线程,保证只有一个子线程处理工作而且是一个一个任务完成的有条不紊。HandlerThread 保证一个loop 一个线程   队列保证顺序

到底还有别的地方用么?

很多地方有这么用

fragment什么生命周期管理

你可能感兴趣的:(Handler)