Handler(17)
Handler是什么?
消息机制是什么?
为什么不能在子线程中访问UI?
在子线程中创建Handler报错是为什么?
如何在子线程创建Looper?
Looper.prepare();
为什么通过Handler能实现线程的切换?
[☆] Handler.post的逻辑在哪个线程执行的,是由Looper所在线程还是Handler所在线程决定的?
由Looper所在线程决定的
最终逻辑是在Looper.loop()方法中,从MsgQueue中拿出msg,并且执行其逻辑,这是在Looper中执行的,因此有Looper所在线程决定。
[☆] Looper和Handler一定要处于一个线程吗?子线程中可以用MainLooper去创建Handler吗?
可以的。
子线程中Handler handler = new Handler(Looper.getMainLooper());,此时两者就不在一个线程中。
Handler的post/send()的原理
通过一系列sendMessageXXX()方法将msg通过消息队列的enqueueMessage()加入到队列中。
Handler的post方法发送的是同步消息吗?可以发送异步消息吗?
用户层面发送的都是同步消息
不能发送异步消息
异步消息只能由系统发送。
[☆]Handler的post()和postDelayed()方法的异同?
底层都是调用的sendMessageDelayed()
post()传入的时间参数为0
postDelayed()传入的时间参数是需要的时间间隔。
Handler的postDelayed的底层机制
MessageQueue.next()会因为发现了延迟消息,而进行阻塞。那么为什么后面加入的非延迟消息没有被阻塞呢?
Handler的dispatchMessage()分发消息的处理流程?
Handler为什么要有Callback的构造方法?
不需要派生Handler
Handler构造方法中通过Looper.myLooper();是如何获取到当前线程的Looper的?
myLooper()内部使用ThreadLocal实现,因此能够获取各个线程自己的Looper
主线程如何向子线程发送消息?
MessageQueue(9)
MessageQueue是什么?
MessageQueue的主要两个操作是什么?有什么用?
[☆] MessageQueue中底层是采用的队列?
错误!
采用单链表的数据结构来维护消息队列,而不是采用队列
MessageQueue的enqueueMessage()方法的原理,如何进行线程同步的?
就是单链表的插入操作
如果消息队列被阻塞回调用nativeWake去唤醒。
用synchronized代码块去进行同步。
MessageQueue的next()方法内部的原理?
分为三种情况进行处理。
next()是如何处理一般消息的?
next()是如何处理同步屏障的?
next()是如何处理延迟消息的额?
[☆]Looper.loop()是如何阻塞的?MessageQueue.next()是如何阻塞的?
通过native方法:nativePollOnce()进行精准时间的阻塞。
Looper(17)
Looper是什么?
[☆] 如何开启消息循环?
Looper.loop();
Looper的构造内部会创建消息队列。
主线程ActivityThread中的Looper的创建和获取
Looper的两个退出方法?
quit和quitSafely有什么区别
子线程中创建了Looper,在使用完毕后,终止消息循环的方法?
Looper.loop()的源码流程?
获取到Looper和消息队列
for无限循环,阻塞于消息队列的next方法
取出消息后调用msg.target.dispatchMessage(msg)进行消息分发
[☆] Looper.loop()在什么情况下会退出?
next方法返回的msg == null
线程意外终止
MessageQueue的next方法什么时候会返回null?
[☆] Looper.quit/quitSafely的本质是什么?
让消息队列的next()返回null,依次来退出Looper.loop()
Looper.loop()方法执行时,如果内部的myLooper()获取不到Looper会出现什么结果?
主线程是如何准备消息循环的?
ActivityThread中的Handler H的作用?
如何获取主线程的MainLooper
Android如何保证一个线程最多只能有一个Looper?如何保证只有一个MessageQueue
Handler消息机制中,一个looper是如何区分多个Handler的?
ThreadLocal(7)
ThreadLocal是什么?
ThreadLocal的作用?
ThreadLocal的两个应用场景?
ThreadLocal的使用
同一个ThreadLocal调用set(xxx)和get()
ThreadLocal的原理
thread.threadLocals就是当前线程thread中的ThreadLocalMap
ThreadLocalMap中有一个table数组,元素是Entry。根据ThreadLocal(需要转换获取到Hash Key)能get到对应的Enrty。
Entry中key为ThreadLocal, value就是存储的数值。
[☆]如何获取到当前线程
Thread.currentThread()就是当前线程。
[☆]如何在ThreadLocalMap中,ThreadLocal如何作为键值对中的key?
通过ThreadLocal计算出Hash key,通过这个哈希值来进行存储和读取的。