Handler是用于操作線程內(nèi)部的消息隊(duì)列的類。這有點(diǎn)繞,沒關(guān)系,我們慢慢的來講。前面Looper一篇講到了Looper是用于給線程創(chuàng)建消息隊(duì)列用的,也就是說Looper可以讓消息隊(duì)列(MessageQueue)附屬在線程之內(nèi),并讓消息隊(duì)列循環(huán)起來,接收并處理消息。但,我們并不直接的操作消息隊(duì)列,而是用Handler來操作消息隊(duì)列,給消息隊(duì)列發(fā)送消息,和從消息隊(duì)列中取出消息并處理。這就是Handler的職責(zé)。 Handler,Looper和MessageQueue是屬于一個(gè)線程內(nèi)部的數(shù)據(jù),但是它提供給外部線程訪問的接口,Handler就是公開給外部線程,與線程通訊的接口。換句話說,這三個(gè)東西都是用來線程間通訊用的(ITC--Inter Thread Communication),與進(jìn)行間通訊(IPC--Inter Process Communication)的消息隊(duì)列msgque的核心思想是一致的。MessageQueue是相對(duì)較底層的,較少直接使用,Looper和Handler就是專門用來操作底層MessageQueue的。 還有一個(gè)重要的數(shù)據(jù)結(jié)構(gòu)是通訊的基本元素,就是消息對(duì)象(Message),Message從來不單獨(dú)使用,它都是跟隨Handler來使用的。具體方法可以參考文檔,但需要注意的是同一個(gè)消息對(duì)象不能發(fā)送二次,否則會(huì)有AndroidRuntimeException: { what=1000 when=-15ms obj=.. } This message is already in use."。每次發(fā)送消息前都要通過Message.obtain()來獲取新的對(duì)象,或者,對(duì)于不需要傳送額外數(shù)據(jù)的直接發(fā)送空消息就好Handler.sendEmptyMessage(int)。另外也需要注意消息對(duì)象是不能手動(dòng)回收的,也就是說你不能調(diào)用Message.recycle()來釋放一個(gè)消息對(duì)象,因?yàn)楫?dāng)該對(duì)象被從隊(duì)列中取出處理完畢后,MessageQueue內(nèi)部會(huì)自動(dòng)的去做recycle()。這個(gè)理解起來也很容易,因?yàn)榘l(fā)送一個(gè)消息到消息隊(duì)列后,消息什么時(shí)候會(huì)被處理,對(duì)于應(yīng)用程序來講是不知道的,只有MessageQueue才會(huì)知道,所以只能由MessageQueue來做回收釋放的動(dòng)作。 因?yàn)镠andler是用于操作一個(gè)線程內(nèi)部的消息隊(duì)列的,所以Handler必須依附于一個(gè)線程,而且只能是一個(gè)線程。換句話說,你必須在一個(gè)線程內(nèi)創(chuàng)建Handler,同時(shí)指定Handler的回調(diào)handlerMessage(Message msg)。 Handler主要有二個(gè)用途,一個(gè)是用于線程內(nèi)部消息循環(huán); 另外一個(gè)就是用于線程間通訊。 Handler的基本用法可以參考文檔,說的還是比較清楚的。 用于線程內(nèi)部消息循環(huán) 主要是用作在將來定時(shí)做某個(gè)動(dòng)作,或者循環(huán)性,周期性的做某個(gè)動(dòng)作。主要的接口就是 Handler.sendEmptyMessageDelayed(int msgid, long after); Handler.sendMessageDelayed(Message msg, long after); Handler.postDelayed(Runnable task, long after); Handler.sendMessageAtTime(Message msg, long timeMillis); Handler.sendEmptyMessageAtTime(int id, long timeMiilis); Handler.postAtTime(Runnable task, long timeMillis); 這些方法的目的都是設(shè)置一個(gè)定時(shí)器,在指定的時(shí)間后,或者在指定的時(shí)間向Handler所在的MessageQueue發(fā)送消息。這樣就非常方便應(yīng)用程序?qū)崿F(xiàn)定時(shí)操作,或者循環(huán)時(shí)序操作(處理消息時(shí)再延時(shí)發(fā)送消息,以達(dá)成循環(huán)時(shí)序)。
public class HandlerSimpleDemo extends Activity { protected static final String TAG = "HandlerSimpleDemo"; private static final int MEDIA_PLAYER_READY = 0; private static final int REFRESH_PROGRESS = 1;