天天看點

Message,Handler,MessageQueue,Looper之間的關系

Message,Handler,MessageQueue,Looper之間的關系

  • Looper:是一個消息分發器,在主線程建立的時候就會建立一個Looper對象;
  • MessageQueue :消息隊列,是由Message組成的一個隊列;
  • Handler :擷取到Message,然後執行動作,可以在主線程和子線程中互相傳遞資料;

先大概說一下他們之間的關系:

在主線程建立之後會建立一個Looper對象,建立Looper對象的時候會去建立一個MessageQueue,而Looper是一個輪詢器,會不停的輪詢MessageQueue中的消息,在擷取到消息之後就會把這個消息交給相應的handler來進行處理,在主線程中建立一個handler對象,這個handler對象把一個Message放到消息隊列中,然後擷取到消息進行處理。

Message,Handler,MessageQueue,Looper之間的關系

線程間通信最常見的就是,子線程需要更新UI:

根據安卓系統的機制,UI隻能在主線程中更新,如果我們想在子線程中更新UI,就要用到這一套機制了,在主線程和子線程之間傳遞資訊。做法就是,現在主線程中建立一個handler對象,Looper對象和MessageQueue對象是不用建立的,因為在主線程建立的時候就建立好了。然後重寫handlerMessage方法,這個方法是在handler接收到message之後執行的方法,我們把更新UI的代碼放到這個方法中。然後再子線程中用sendEmptyMessage方法來發送一個消息到消息隊裡。在發送完這個消息之後,Looper這個輪詢器因為一直在輪詢消息隊列。獲得到這個消息之後就會執行handlerMessage方法,因為這個方法是在主線程中實作的。是以UI就可以更新了。

那要是在主線程中給子線程發送消息呢?

在主線程中給子線程發送消息:在子線程中new出來一個handler對象,然後重寫handlerMessage方法,在主線程sendemptymessage,但這樣是不行的,因為handler要處理消息,但是在子線程中是沒有Looper對象的,我們要通過Looper.prepar來建立一個Looper對象, 在這裡Looper對像被建立的時候會建立一個MessageQueue,這樣就有Looper了,然後再執行完操作之後要執行以下Looper.loop方法,去輪詢這些消息,讓handler來處理這些消息。在安卓的源代碼中,Looper.loop()方法是一個永遠為true的while死循環,是以我們要在子線程中執行的動作,都要在這個方法前去執行,如果在這個方法後去執行的話,就不能被執行到了。