天天看点

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