Handler 之 Message的復用機制

2021-09-29 07:43:42 字數 1848 閱讀 5372

android如何處理訊息?

android是基於訊息驅動的系統,訊息處理機制自然重中之重 ,一句話大體說一下:每個執行緒用過threadlocal保證儲存的looper執行緒唯一性,looper.preapre中會建立乙個該執行緒的messagequeue(乙個儲存message的訊息單鏈表),而將訊息插入到messagequeue的執行者就是handler,所以乙個執行緒中乙個looper,乙個messagequeue,大量message,多個handler,下圖很好的解釋了取資料以及分發資料的流程:

message如何建立?

既然android是基於訊息機制,那麼android不斷的建立meaage到messagequeue中,堆中是不是會不斷的新物件的建立以及銷毀,導致記憶體抖動,而gc執行緒雖然作為優先順序最低的執行緒,此時因為必須gc,導致gc執行緒搶占cpu時間片,主線程拿不到cpu而卡頓調幀。google在設計訊息機制的時候就想到了訊息復用機制,幾乎所有framework中傳送訊息都是通過message.obtain來進行訊息復用,接下倆看一下如何復用:

在主線程looper的loop()中不斷的從訊息佇列中取訊息diapatch,分發之後會呼叫message的**操作,省略了部分**:

public static void loop() 

msg.target.dispatchmessage(msg); // 分發訊息

msg.recycleunchecked(); // **}}

可以看到當訊息分發完成後將message進行recycle:

void recycleunchecked() }}

接著看一下message物件的幾個成員:

/*package*/ message next;   // 為了形成訊息鍊錶

public static final object spoolsync = new object(); // 物件鎖

private static message spool; // 訊息鍊錶的頭節點

private static int spoolsize = 0; // 當前鍊錶中資料的個數

private static final int max_pool_size = 50; // 總共可使用的訊息鍊錶大小

基於上面可以看出訊息**後的策略,下面就是訊息獲取的策略:

public static message obtain() 

}return new message(); // 如果訊息鍊錶為空 建立新的message

}

總結:

message通過靜態單鏈表來全域性完成訊息的復用,而在每次**的過程中訊息資料重置防止message持有其他物件而造成記憶體洩漏操作,所有在日常開發開發中盡量使用mesaage.obtain來獲取message,如果手動建立message,也不是不行,因為looper的訊息在使用完都會自動呼叫recycle的,但是一旦訊息鍊錶到達上限,那麼如果大量傳送訊息 ,仍然存在大量message物件需要在堆中**的問題。

handler 封裝任務 Message

在整個訊息處理機制中,message又叫task,封裝了任務攜帶的資訊和處理該任務的handler。message的用法比較簡單,這裡不做總結了。但是有這麼幾點需要注意 待補充 1.儘管message有public的預設構造方法,但是你應該通過message.obtain 來從訊息池中獲得空訊息物件...

Handler機制 3 Message簡介

二 message 概述message是負責承載訊息的類,主要是關注他的內部屬性 使用者自定義,主要用於辨別message的型別 public int what 用於儲存一些整型資料 public int arg1 public int arg2 可放入乙個可序列化物件 public object ...

handler原始碼學習(2) Message

這是handler原始碼學習第二篇,後續還有 handler原始碼學習 1 handler handler原始碼學習 2 message handler原始碼學習 3 looper handler原始碼學習 4 messagequeue message相對來說比較簡單,大部門 都是對一些屬性值的賦值...