作為一個Android的初學(xué)者蝴悉,對于Handler的機制與用法可以說是門外漢。什么是Handler,如何傳遞 Message祭示,傳遞 Runnable 對象,傳遞 Callback 對象谴古,Handler 原理是什么?下面我就以一個初學(xué)者的視角為大家介紹這些知識质涛。
首先稠歉,關(guān)于什么是Handler。當(dāng)應(yīng)用程序啟動時汇陆,Android首先會開啟一個主線程 (也就是UI線程) 怒炸, 主線程為管理界面中的UI控件, 進行事件分發(fā)瞬测,比如說横媚,你要是點擊一個 Button ,Android會分發(fā)事件到Button上月趟,來響應(yīng)你的操作灯蝴。如果此時需要一個耗時的操作,例如: 聯(lián)網(wǎng)讀取數(shù)據(jù)孝宗, ?或者讀取本地較大的一個文件的時候穷躁,你不能把這些操作放在主線程中,如果你放在主線程中的話因妇,界面會出現(xiàn)假死現(xiàn)象问潭, 如果5秒鐘還沒有完成的話,會收到Android系統(tǒng)的一個錯誤提示? "強制關(guān)閉"婚被。? 這個時候我們需要把這些耗時的操作狡忙,放在一個子線程中,因為子線程涉及到UI更新址芯,Android主線程是線程不安全的灾茁, 也就是說,更新UI只能在主線程中更新谷炸,子線程中操作是危險的北专。 這個時候,Handler就出現(xiàn)了來解決這個復(fù)雜的問題 旬陡,由于Handler運行在主線程中(UI線程中)拓颓,? 它與子線程可以通過Message對象來傳遞數(shù)據(jù), 這個時候描孟,Handler就承擔(dān)著接受子線程傳過來的Message對象驶睦,把這些消息放入主線程隊列中,配合主線程進行更新UI匿醒。
介紹完了Handler场航,下面就來介紹介紹他能干什么。handler可以分發(fā)Message對象和Runnable對象到主線程中青抛, 每個Handler實例旗闽,都會綁定到創(chuàng)建他的線程中(一般是位于主線程),它有兩個作用:
(1)安排消息或Runnable 在某個主線程中某個地方執(zhí)行;
(2)安排一個動作在不同的線程中執(zhí)行适室。
傳遞 Message的示例代碼:
post(Ruannable);
postAtTime(Runnable,long);
postDelayed(Runnablelong);
傳遞 Runnable 對象的示例代碼
sendEmptyMessage(int);
sendMessage(Message);
sendMessageAtTime(Message,long);
sendMessageDelayed(Message,long);
sendMessage 類方法嫡意,允許你安排一個帶數(shù)據(jù)的 Message 對象到隊列中,等待更新捣辆。
傳遞 Callback 對象的示例代碼:
publicHandler mHandler =newHandler(newHandler.Callback(){
@Override
publicbooleanhandleMessage(Message msg){
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"HandleMessage 1", Toast.LENGTH_SHORT).show();
returntrue;? ?
?}
})?
{
publicvoidhandleMessage(Message msg){
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"handleMessage 1", Toast.LENGTH_SHORT).show();? ? };
}
關(guān)于Handler 的原理蔬螟,作為一個初學(xué)者,看了也是一知半解汽畴,就只能依葫蘆畫瓢地解釋一波旧巾。
Handler 封裝了消息的發(fā)送(主要包括消息發(fā)送給誰) Looper:內(nèi)部包含一個消息隊列也就是 MessageQueue,所有 Handler 發(fā)送的消息都走向這個隊列忍些。Looper.loop()方法鲁猩,就是一個 for 死循環(huán),不斷的從 MessageQueue 取消息罢坝,如果有消息就處理消息廓握,沒有消息就阻塞。MessageQueue嘁酿,就是一個消息隊列隙券,可以添加消息,處理消息闹司。Handler 也不難娱仔,比較簡單,在構(gòu)造 Handler 時候內(nèi)部會跟 Looper 進行關(guān)聯(lián)游桩,通過 Looper.myLooper() 獲取到 Looper牲迫,找到 Looper 也就找到了 MessageQueue。在 Handler 中發(fā)送消息众弓,其實是向 MessageQueue 隊列中發(fā)送消息恩溅。