Handler四件套:
Looper套媚,MessageQueue(MQ),Handler和Message
Looper:消息輪詢器磁椒,持有消息隊(duì)列,并輪詢該隊(duì)列以提供給Handler消息浆熔。
- 私有構(gòu)造器,構(gòu)造器內(nèi)創(chuàng)建消息隊(duì)列MQ慎皱,使用前需調(diào)用其封裝函數(shù)prepare()叶骨,其內(nèi)為初始化校驗(yàn),并結(jié)合ThreadLocal忽刽,保證本對(duì)象的線程作用域的有效且本線程內(nèi)該對(duì)象的唯一性;
- 類級(jí)別持有主線程的Looper對(duì)象,自身對(duì)象通過myLooper()方法對(duì)外提供洁闰,持有MQ對(duì)象扑眉,MQ與當(dāng)前線程對(duì)應(yīng),未prepare的線程不能創(chuàng)建handler;
- 輪詢消息腰素,涉及底層操作,線程可能阻塞衡便,包括UI線程(阻塞時(shí),可被其它進(jìn)程IPC喚醒)镣陕,找到消息后傳遞給該消息的目標(biāo)處理器(msg.target,Handler類型岂嗓,不一定是發(fā)送本消息的target)鹊碍,調(diào)用handler.dispatchMessage()。
MessageQueue:單鏈表實(shí)現(xiàn)的阻塞隊(duì)列侈咕,提供消息對(duì)象的存取等操作。
- MQ的創(chuàng)建發(fā)生在Looper對(duì)象創(chuàng)建之時(shí)熏兄,作用域?yàn)楫?dāng)前Looper所在線程树姨,即一個(gè)線程,一個(gè)Looper硝清,一個(gè)MQ转晰;
- 鏈表實(shí)現(xiàn)的隊(duì)列,具有常規(guī)的插入查邢、刪除、判空扰藕,查詢等操作,與native交互較多;
- 核心方法是插入enqueueMessage和分發(fā)next未桥,插入是由Handler對(duì)象調(diào)用芥备,經(jīng)多次校驗(yàn),通過鏈表操作執(zhí)行插入亦镶,next由Looper對(duì)象調(diào)用,經(jīng)過native調(diào)用得到msg染乌,并返給Looper,然后再返給Handler台颠。
Handler:消息對(duì)象的調(diào)度和處理者勒庄。
- 三種消息處理模式,按優(yōu)先級(jí)降序分別為:消息自帶執(zhí)行器Runnable荡碾,消息代理處理器Handler.CallBack以及Handler本身局装;Runnable的方式是消息分發(fā)(dispatchMessage)后即執(zhí)行其run方法,其它兩個(gè)是handleMessage方法處理铐尚;
- 多個(gè)重載構(gòu)造函數(shù)拨脉,主要是指定Looper對(duì)象和消息代理處理器Handler.CallBack,默認(rèn)構(gòu)造器將在當(dāng)前線程宣增,由Handler本身處理消息玫膀;
- 發(fā)送消息有兩種方式,send和post爹脾,send類型多個(gè)方法最終都是調(diào)用sendMessageAtTime帖旨,即在將來某個(gè)時(shí)刻發(fā)送消息,post最終也是調(diào)用send灵妨,最大的差別是post的消息的最終處理者默認(rèn)是消息自帶執(zhí)行器Runnable解阅。
Message: 數(shù)據(jù)的攜帶者,線程內(nèi)/間信息的載體泌霍。
- 內(nèi)有最大容量為50的消息對(duì)象池货抄,復(fù)用對(duì)象減少開銷烹吵,故不建議用其構(gòu)造函數(shù)來創(chuàng)建Message對(duì)象碉熄,而是應(yīng)該用obtain方法桨武,本方法多次重載肋拔,目的基本都是指定處理器和一些交互數(shù)據(jù);
- 可以通過Bundle數(shù)據(jù)包來發(fā)送任意類型的數(shù)據(jù)setData(Bundle data)呀酸,不過一般采用更低成本的what,arg1,arg2,obj1凉蜂;
- 可以在構(gòu)造函數(shù)或者setTarget(Handler target)里設(shè)置處理器,這里可以看出,發(fā)送消息的handler窿吩,未必是處理消息的handler茎杂,還可以在其中一個(gè)構(gòu)造器內(nèi)設(shè)置自帶消息執(zhí)行器Runnable。