看圖
Looper是一個消息分發器,在主線程創建的時候就會創建一個Looper對象
messageQueue :消息隊列,是由message組成的一個 隊列
handler:從messageQueue中獲取到message,然後執行動作,可以再主線程和子線程中互相傳遞數據
看了源碼之後大概的說一下他們的關係:
在主線程創建之後會創建一個Looper對象,創建Looper對象的時候會去創建一個messageQueue,而Looper是一個輪詢器,會不停的輪詢messageQueue中的消息,在獲取到消息之後就會把這個消息交給handler來進行處理,在主線程中創建一個handler對象,這個handler對象不僅可以獲取到消息進行處理,也可以把一個消息放到消息隊列中。
舉個例子來說明一下: 在子線程中更新UI
根據安卓系統的機制,UI只能在主線程中更新,如果我們想在子線程中更新UI,就要用到這一套機制了,在主線程和子線程之間傳遞信息。
做法就是,現在主線程中創建一個handler對象,Looper對象和messageQueue對象是不用創建的,因爲在系統源碼中這個是在主線程創建的時候就創建好的。然後重寫handlerMessage()方法,這個方法是在handler接收到message之後執行的方法,我們把更新UI的代碼放到這個方法中。然後再子線程中用sendEmptyMessage()方法來發送一個消息到消息隊裏。在發送完這個消息之後,Looper這個輪詢器因爲一直在輪詢消息隊列。獲得到這個消息之後就會執行handlerMessage()方法,因爲這個方法是在主線程中實現的。所以UI就可以更新了。
handler機制:可以在主線程中給子線程發送消息,也可以在子線程中給主線程發送消息:
在子線程中給主線程發送消息:在主線程中創建一個handler對象,然後重寫handlmessage()方法,在子線程中調用handler.sendEmptyMessage()方法,然後在handlermessage()
方法中就可以執行我們想要執行的操作了,比如說更新UI
在主線程中給子線程發送消息:在子線程中new出來一個handler對象,然後重寫handlerMessage方法,在主線程sendemptymessage();只是這樣是不行了,因爲handler要處理消息,但是在子線程中是沒有Looper對象的,我們要通過Looper.prepar()來創建一個Looper對象,
在這裏Looper對像被創建的時候會創建一個MessageQueue,這樣就有Looper了,然後再執行完操作之後要執行以下Looper.loop()方法。去輪詢這些消息,讓handler來處理這些消息。在安卓的源代碼中,Looper.loop()方法是一個永遠爲true的while循環,所以我們要在子線程中執行的動作,都要在這個方法前去執行,如果在這個方法後去執行的話,就不能被執行到