Android之Handler的用法

在上一篇的文章中摆寄,我們提到了在子線程中是無法對UI界面進(jìn)行更新的。那么為啥android中無法在子線程中隊UI進(jìn)行更新呢踩窖?既然這樣又如何才能在子線程中對UI進(jìn)行更新呢翘县?這就是我們這篇文章所要聊聊的。

其實所謂的在子線程中無法對UI進(jìn)行更新市袖,這句話是不嚴(yán)謹(jǐn)?shù)姆戎保鋵嵕€程能否更新UI的關(guān)鍵在于viewroot是否在該線程烁涌。

每當(dāng)我們打開一個android app時,android就會開辟一個對應(yīng)的主線程酒觅,而這個主線程就是這個app的UI線程撮执,即ActivityThread。UI線程主要負(fù)責(zé)與UI相關(guān)的事件舷丹。android系統(tǒng)并不會為每個組件去單獨創(chuàng)建一個線程抒钱。所以android UI操作不是線程安全的,所有的操作都必須在UI線程中執(zhí)行颜凯。即android使用的是單線程模型谋币。

那么android就為我們提供了一個很好用的工具Handler,它允許我們在子線程中去對UI進(jìn)行操作症概。那么Handler究竟該如何使用呢瑞信?

閑話少說,直接提問穴豫,如何做到每2秒去更新UI界面中的一個TextView凡简。

在java中,這可以說很容易實現(xiàn)精肃,直接調(diào)用TimerTask即可秤涩。但是在android中這樣去寫,我們可以發(fā)現(xiàn)并不能達(dá)到我們預(yù)期的效果司抱。那么現(xiàn)在使用Handler來試試看筐眷。

```

public class MainActivity extends Activity {

private int i = 0;

private TextView tv;

private Handler handler = new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case 1:

update();

break;

default:

break;

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv = (TextView) findViewById(R.id.tv);

Timer timer = new Timer();

timer.scheduleAtFixedRate(new MyTask(), 1, 1000*2);

}

private class MyTask extends TimerTask{

@Override

public void run() {

// TODO Auto-generated method stub

Message message = new Message();

message.what = 1;

handler.sendMessage(message);

}

}

private void update() {

// TODO Auto-generated method stub

tv.setText(i+"");

i++;

}

}

```

相信看了上面的代碼,已經(jīng)對Handler的用法有了初步的了解习柠。但是對Handler的用法不僅要知其然匀谣,還要知其所以然。

1.Handler是Android提供的一種異步回調(diào)機制资溃,在Ui線程中使用handler需要new一個handler對象武翎,并重寫其中的handleMessage(Message msg)方法,處理如更新UI等操作溶锭。

從原理上來講宝恶,使用了Hanlder對象的線程需要綁定一個Looper對象,該對象維護(hù)一個消息隊列趴捅,Looper對象取出該隊列的消息后交由handler進(jìn)行處理垫毙。所以在使用Handler時,要調(diào)用Looper.prepare()方法給當(dāng)前的線程綁定一個Looper對象拱绑。
然后調(diào)用loop()建立對消息隊列的循環(huán)综芥,在消息隊列中取出消息后交由相應(yīng)的handler進(jìn)行處理。由于一個線程中可能有多個handler猎拨,為了區(qū)分這些不同的hanlder所需要處理的消息膀藐,每個Message對象都維護(hù)有一個hanlder實例即target征峦,在loop方法中通過調(diào)用msg.target.dispatchMessage(msg)進(jìn)行處理。每個線程只能綁定一個loop對象消请,多個handler共享,handler的在構(gòu)造時從當(dāng)前的線程中取得loop對象类腮,Looper中的myLooper中返回了sThreadLocal.get()所取得的Looper對象臊泰。所以,在使用handler中需要執(zhí)行以下步驟蚜枢,首先調(diào)用Looper.prepare()方法為當(dāng)前線程綁定Looper對象缸逃,然后才可以實例化一個Handler對象,最后調(diào)用loop()方法建立消息循環(huán)厂抽。

2.Handler還有另一個作用就是延遲處理需频。

我們知道在android中,若點擊一個Button后5s沒有反應(yīng)就會出現(xiàn)ANR的問題筷凤。那么此時Hanlder的作用就凸顯出來了昭殉。

如果我們有一個需求,需要程序在點擊一個Button后藐守,6秒后彈出一個Toast挪丢。那么很容易就想到的一個解決辦法就是Thread.sleep(1000*6)。然后在用Handler里彈出來一個Toast卢厂。但是明顯6秒超出了androidUI線程的5秒的限制乾蓬。查看Handler的方法,我們發(fā)現(xiàn)Handler有個Handler.postDelayed(Runnable r, long delayMillis)的方法慎恒。那么這個問題就很容易解決了任内。

new Handler().postDelayed(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

Toast.makeText(MainActivity.this, "延遲處理", Toast.LENGTH_SHORT).show();

}

}, 1000*5);

總結(jié)一下,Handler的兩大用法:1)在子線程中更新主線程融柬;2)延遲處理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末死嗦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子粒氧,更是在濱河造成了極大的恐慌越走,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靠欢,死亡現(xiàn)場離奇詭異廊敌,居然都是意外死亡,警方通過查閱死者的電腦和手機门怪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門骡澈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人掷空,你說我怎么就攤上這事肋殴《陲保” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵护锤,是天一觀的道長官地。 經(jīng)常有香客問我,道長烙懦,這世上最難降的妖魔是什么驱入? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮氯析,結(jié)果婚禮上亏较,老公的妹妹穿的比我還像新娘。我一直安慰自己掩缓,他們只是感情好雪情,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著你辣,像睡著了一般巡通。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舍哄,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天扁达,我揣著相機與錄音,去河邊找鬼蠢熄。 笑死跪解,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的签孔。 我是一名探鬼主播叉讥,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼饥追!你這毒婦竟也來了图仓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤但绕,失蹤者是張志新(化名)和其女友劉穎救崔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捏顺,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡六孵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了幅骄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劫窒。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拆座,靈堂內(nèi)的尸體忽然破棺而出主巍,到底是詐尸還是另有隱情冠息,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布孕索,位于F島的核電站逛艰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏搞旭。R本人自食惡果不足惜散怖,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望选脊。 院中可真熱鬧,春花似錦脸甘、人聲如沸恳啥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钝的。三九已至,卻和暖如春铆遭,著一層夾襖步出監(jiān)牢的瞬間硝桩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工枚荣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碗脊,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓橄妆,卻偏偏與公主長得像衙伶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子害碾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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