子執行緒中建立Handler可以嗎?(上)

youou發表於2021-09-09

本文包括與Handler有關的以下問題:

  (1)Handler的作用

  (2)為什麼Android中要設計為只能在UI執行緒中去更新UI呢?

  (3)Handler的兩個異常

  (4)Handler、Looper MessageQueue之間的關係(原始碼角度)

  (5)跟執行緒相關的Handler,即HandlerThread(原始碼角度分析)

  (6)主執行緒往子執行緒發訊息

一、Handler的作用:

(1)在非UI執行緒中完成耗時操作,在UI執行緒中去更新UI。

(2)可以在主執行緒中傳送延時訊息。

二、為什麼Android中要設計為只能在UI執行緒中去更新UI呢?

(1)解決多執行緒併發問題(根本原因)

(2)提高介面更新的效能問題

(3)架構設計的簡單

你可能會說,既然是擔心多執行緒併發問題,那我在子執行緒中加鎖進行更新UI行不行呢?你這樣想的話,會容易造成UI卡頓的,而且效能也不好。

注1:大部分面試者很難去說出一個令面試官滿意的答案。

注2:關於多執行緒,這裡舉一個例子,比如說銀行取款的問題。正常情況下,銀行卡餘額不能少於取款金額,如果多執行緒進行取款的話,就會造成執行緒不安全。

注3:Android中之所以說架構簡單,是因為幫我們封裝了很多更新UI的操作。

三、Handler的兩個異常:

在使用Handler時,經常會出現以下兩個異常:

(1)CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views:此異常是因為嘗試在子執行緒中去更新UI,進而報錯。

(2)Can’t create handle inside thread that ha not called Looper.prepared:是因為我們在子執行緒中去建立Handler,而產生的異常。

我們接下來透過程式碼來把這兩個異常演示一下。

1、子執行緒中更新UI的異常:

(1)activity_main.xml:
圖片描述
上方程式碼中,一個文字,一個按鈕,程式碼比較簡單。
(2)MainActivity.java:
圖片描述
上方程式碼中,核心程式碼是第45行:點選按鈕後,在子執行緒中更新UI。
我們來看一下後臺的log日誌:
圖片描述
上圖中報的錯誤日誌就是因為我們在子執行緒中去更新UI。
解決方案:
  在子執行緒中建立Message訊息,透過Handler發給主執行緒,之後在Handler的handleMessage方法中獲得Message訊息,進而處理更新UI介面。程式碼如下:
圖片描述
上方第50行程式碼也可以換成51行程式碼:

2、在子執行緒中建立Handler的異常:

MainActivity.java:
圖片描述
執行程式後, 報錯如下:
圖片描述

非原創,參考自:http://blog.csdn.net/erliangcode/article/details/52117831

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4729/viewspace-2808262/,如需轉載,請註明出處,否則將追究法律責任。

相關文章