Thread

基礎介紹

liy Elaine
liy Elaine
4 min readSep 18, 2020

--

大家會不會好奇那麼多程式碼,背後到底是誰推進的呢?
那會是怎麼樣的機制呢?

答案是線程(Thread), 在程式碼背後 他就像一個馬達驅動程式碼的執行

組成

Looper : 可有可無 ,和 MessageQueue 是一組的

Handler : 要有 Looper 的地方 , 才會有 Handler

MessageQueue: 可有可無 ,和 Looper 是一組的

Message :整個線程驅動的對象

Looper 從何而來?

在主線程線 , 系統會自動初始化一個Looper, 所以我們並不需要手動去添加 Looper , 但在 工作線程(非UI 線程)預設 是沒有 Looper , 我們需要透過 去調用 Looper .prepare () 生成一個 Looper 。如果在 未調用 Looper . prepare() 情形下 , 去調用工作線程的 Handler 會報錯。

每個角色的分工

  • Looper : 可以看成一個抽水馬達,透過調用 Loop.looper(), 形成一個循環,不斷地從MessageQueue中提取Message
  • Message : 要執行的程式碼, 可以看成是水, Message會關聯 送出他的 Handler , 當 輪到這個 Message , Looper會把它取出 , 送出它的 Handler 會把它處理掉
  • Handler : 負責向 MessageQueue 添加 Message , 和處理自己送出的 Message。
  • MessageQueue : Looper對象通過MessageQueue來存放消息和事件,所有的 Message 在此駐隊排列 , Looper.loop()調用 MessageQueue.next() 方法取Message

如何去送出 Message?

Handler 可以透過 post 類 (post , postAtTime ,postDelayed)或 send 類 (sendEmptyMessage , sendMessage ,sendMessageAtTime)的 function 將訊息送出, Handler 會透過 調用 sendMessageAtTime() 來將其加入到MessageQueue中

如何去消費 Message?

Looper 會不斷地 的 從 MessageQueue提取 Message,提取的消息 Looper 並沒有做處理 , 那提取的消息到底跑去哪了?這是我一開始很疑惑的點 , 後來明白了他的機制。 前面 有提到 Handler 會處理自己送出的 Message 出自己 , 於是開始腦補 到底是怎樣的概念,都已經排進去 ,要如何知道是誰送出他的啊。

重點在這段代碼, 這段代碼確保了Message 可以找到 送出他的 Handler , 透過 dispatchMessage 消費 這個 Message

異步更新 UI

在 非主線程 執行異步程式碼 , 當執行完成獲取執行結果後 , 想要更新 UI 畫面 , 這時候可以透過調用主線程 的 Handler 在 非主線程 中 發送 Message 到 主線程的 MessageQueue , 等到輪到這個 Message 時, Looper 將這個 Message取出 , 這個發送的 Handler 會處理這個Message , 去執行更新畫面

在Activity中新建一个handler , 當 handler 處理 發送的 Message , 會調用 Callback , 我們 可以在這個 callback 中獲取 在非主線程送出的訊息內容 , 並更新 UI 畫面

主線程 handler 在非主線程中 向主線程 MessageQueue 發送 Message

--

--