天天看點

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,通過這個哈希值來進行存儲和讀取的。