Handler你所不知道的技巧

作為一個Android開發(fā)人員 ,如果對android的消息處理機(jī)制不明白的話沟使,那就有點(diǎn)說不過去了青扔,至于有關(guān)消息處理機(jī)制在這里我就不多說了晓猛,各位請自行Google或者百度 栽连,不過我在這里還是總結(jié)一下有關(guān)消息處理機(jī)制的幾個類之間的關(guān)系:ToastUtil.showFailTop(error_message);


總結(jié)一下:

1.一個Thread只對應(yīng)一個Looper

2.一個Looper對象只對應(yīng)一個MessageQueue

3.一個MessageQueue對應(yīng)多個Messsage

4.一個Message只對應(yīng)一個Handler

所以上述結(jié)論是:一個Thread可以對應(yīng)多個Handler.

好了险领,上述大概都是大家都知道的,接下來我們就來說下大家不知道的。

先給大家描述一下這樣的一個情景:

你開啟了一個后臺線程 但是這個線程要往下執(zhí)行 必須等待另一個運(yùn)行在Hanlder線程下的Task的結(jié)果绢陌,得不到這個結(jié)果 你程序就無法往下進(jìn)行挨下,即使能往下進(jìn)行也沒有實(shí)際意義。此時你會想到如何解決這個問題呢下面?

你肯定想著我讓我當(dāng)前線程阻塞 ,然后呢等另一個線程上的任務(wù)完成后绩聘,通知我這個線程繼續(xù)往下運(yùn)行沥割,這就運(yùn)用到了Object上帝對象的wait 和 notifiy or notifyAll方法了。

其實(shí)Android系統(tǒng)中有很多這樣的一個場景凿菩,我隨便舉個例子來給大家說明一下:



這就是Android系統(tǒng)系統(tǒng)systemserver進(jìn)程的時候所調(diào)用的一行代碼机杜,這個函數(shù)的邏輯很清楚 ,就是初始化一個WindowManagerService實(shí)例對象衅谷,但是這里運(yùn)用了一個Handler的一個技巧椒拗,那就是只有當(dāng)runWithScissors方法中的Runnable任務(wù)執(zhí)行完成后,也就是WindowManagerService構(gòu)造完成之后才能返回获黔,否則如果連最重要的WMS都沒有初始化成功 蚀苛,那么Android系統(tǒng)就沒有繼續(xù)進(jìn)行下去的理由了,那么我們就來看下這里具體是如何實(shí)現(xiàn)的玷氏。


我們來看重點(diǎn) ?:第三個if判斷條件 ?其實(shí)就是判斷 我們當(dāng)前運(yùn)行的線程是否跟Handler所在的線程一致 堵未,如果一致的話 那么就世界運(yùn)行Runnable的run方法 ?如果不是 那么就要涉及到等待喚醒機(jī)制了 ?而這個機(jī)制就是靠BlockingRunnable來實(shí)現(xiàn)的,我們來看下具體的實(shí)現(xiàn)代碼:


核心代碼就是這個 盏触,我們看到 首先就是將任務(wù)添加到Hanlder對應(yīng)的MessageQueue隊(duì)列中去渗蟹,如果添加成功才繼續(xù)往下運(yùn)行,

這里我們只考慮添加成功的情況:

?然后進(jìn)入到了同步代碼塊中:

? ?我們看到有一個while循環(huán)赞辩,并且標(biāo)志位是一個mDone 這是BlockingRunnable的一個成員變量 ?默認(rèn)值是false ?我們發(fā)現(xiàn)這里的代碼的邏輯就是如果任務(wù)添加成功 然后就在該對象監(jiān)視器(this)上阻塞 雌芽,直到被喚醒。 那么我們猜想一下肯定是mDone的值影響到了代碼的邏輯 辨嗽,我們看下這個值是如何被改變的世落。


我們看到了 只有當(dāng)run方法運(yùn)行完成之后 ?然后才會去設(shè)置mDone的值 然后通知阻塞到該監(jiān)視器上的線程 ?,這樣就做到了 一個后臺線程需要等待另一個線程的執(zhí)行結(jié)果的時候的一種方式 ?我相信很多人不看源碼的話 是不會知道有這么個技巧的糟需,但是這個方法是HIDE的 如果我們想要實(shí)現(xiàn)類似的邏輯的話 我們就要使用反射 來進(jìn)行岛心,大家盡量不要濫用 ,一定要考慮清楚自己的場景之后 結(jié)合實(shí)際去選擇合適的方法 篮灼,這里我貼一下我反射的代碼 :

handler=newHandler() {

@Override

public?voidhandleMessage(Messagemsg)?{

super.handleMessage(msg);

}

};

Log.e("FormalCourseFrag","阻塞方法開始執(zhí)行--"+SystemClock.elapsedRealtime());

Classc;

Methodmethod;

try{

Class[]argsClass=newClass[2];

argsClass[0]=Runnable.class;

argsClass[1]=long.class;

Object[]params=newObject[2];

params[0]=newRunnable()?{

@Override

public?voidrun()?{

try{

Thread.sleep(10000);

}catch(InterruptedExceptione)?{

e.printStackTrace();

}

}

};

params[1]=0;

c=Class.forName("android.os.Handler");

method=c.getMethod("runWithScissors",argsClass);

method.invoke(handler,params);

}catch(ClassNotFoundExceptione)?{

e.printStackTrace();

}catch(NoSuchMethodExceptione)?{

e.printStackTrace();

}catch(InvocationTargetExceptione)?{

e.printStackTrace();

}catch(IllegalAccessExceptione)?{

e.printStackTrace();

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末忘古,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子诅诱,更是在濱河造成了極大的恐慌髓堪,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異干旁,居然都是意外死亡驶沼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門争群,熙熙樓的掌柜王于貴愁眉苦臉地迎上來回怜,“玉大人,你說我怎么就攤上這事换薄∮裎恚” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵轻要,是天一觀的道長复旬。 經(jīng)常有香客問我,道長冲泥,這世上最難降的妖魔是什么驹碍? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮凡恍,結(jié)果婚禮上志秃,老公的妹妹穿的比我還像新娘。我一直安慰自己嚼酝,他們只是感情好洽损,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著革半,像睡著了一般碑定。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上又官,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天延刘,我揣著相機(jī)與錄音,去河邊找鬼六敬。 笑死,一個胖子當(dāng)著我的面吹牛普泡,可吹牛的內(nèi)容都是我干的砰嘁。 我是一名探鬼主播件炉,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼斟冕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缅阳,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤磕蛇,失蹤者是張志新(化名)和其女友劉穎秀撇,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弄唧,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年麸俘,在試婚紗的時候發(fā)現(xiàn)自己被綠了紧憾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愈涩。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖淹父,靈堂內(nèi)的尸體忽然破棺而出株婴,到底是詐尸還是另有隱情,我是刑警寧澤暑认,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布困介,位于F島的核電站,受9級特大地震影響蘸际,放射性物質(zhì)發(fā)生泄漏座哩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一捡鱼、第九天 我趴在偏房一處隱蔽的房頂上張望八回。 院中可真熱鬧,春花似錦驾诈、人聲如沸缠诅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽管引。三九已至,卻和暖如春闯两,著一層夾襖步出監(jiān)牢的瞬間褥伴,已是汗流浹背谅将。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留重慢,地道東北人饥臂。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像似踱,于是被迫代替她去往敵國和親隅熙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容