Android面试题-Handler消息机制(50题)

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,通过这个哈希值来进行存储和读取的。
 

你可能感兴趣的:(Android)