handler通俗講就是在各個進程之間發送數據的處理對象。在任何進程中,只要得到了另外一個進程的handler則能夠經過 handler.sendMessage(message)方法向那個進程發送數據。基於這個機制,咱們在處理多線程的時候能夠新建一個thread,這 個thread擁有UI線程中的一個handler。當thread處理完一些耗時的操做後經過傳遞過來的handler向UI線程發送數據,由UI線程去更新界面。
Handler類簡介
在Android平臺中,新啓動的線程是沒法訪問Activity裏的Widget的,固然也不能將運行狀態外送出來,這就須要有Handler機 制進行消息的傳遞了,Handler類位於android.os包下,主要的功能是完成Activity的Widget與應用程序中線程之間的交互。接下 來對該類中經常使用的方法進行介紹,以下表所示。
Handler類的經常使用方法
android
方法簽名
多線程
描 述
app
public void handleMessage (Message msg)
eclipse
子類對象經過該方法接收信息
ide
public final boolean sendEmptyMessage (int what)
函數
發送一個只含有 what 值的消息
oop
public final boolean sendMessage (Message msg)
post
發送消息到 Handler ,
經過 handleMessage 方法接收
this
public final boolean hasMessages (int what)
線程
監測消息隊列中是否還
有 what 值的消息
public final boolean post (Runnable r)
將一個線程添加到消息隊列
開發帶有Handler類的程序步驟以下。 在Activity或Activity的Widget中開發Handler類的對象,並重寫handleMessage方法。 在新啓動的線程中調用sendEmptyMessage或者sendMessage方法向Handler發送消息。 Handler類的對象用handleMessage方法接收消息,而後根據消息的不一樣執行不一樣的操做。 在Android 中Handler和Message、Thread有着很密切的關係。Handler 主要是負責Message的分發和處理。可是這個Message從哪裏來的呢?Message 由一個消息隊列進行管理,而消息隊列卻由一個Looper進行管理。Android系統中Looper負責管理線程的消息隊列和消息循環,具體實現請參考Looper的源碼。 能夠經過Loop.myLooper()獲得當前線程的Looper對象,經過Loop.getMainLooper()能夠得到當前進程的主線程的 Looper對象。Android系統的消息隊列和消息循環都是針對具體線程的,一個線程能夠存在(固然也能夠不存在)一個消息隊列和一個消 息循環(Looper),特定線程的消息只能分發給本線程,不能進行跨線程,跨進程通信。可是建立的工做線程默認是沒有消息循環和消息隊列的,若是想讓該 線程具備消息隊列和消息循環,須要在線程中首先調用Looper.prepare()來建立消息隊列,而後調用Looper.loop()進入消息循環。 雖然說 特定線程的消息只能分發給本線程,不能進行跨線程通信,可是因爲能夠經過得到線程的Looper對象來進行曲線的實現不一樣線程間消息的傳遞,代碼以下 package com.mytest.handlertest; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class HandlerTest extends Activity implements OnClickListener{ private String TAG = "HandlerTest"; private boolean bpostRunnable = false; private NoLooperThread noLooperThread = null; private OwnLooperThread ownLooperThread = null; private ReceiveMessageThread receiveMessageThread =null; private Handler mOtherThreadHandler=null; private EventHandler mHandler = null; private Button btn1 = null; private Button btn2 = null; private Button btn3 = null; private Button btn4 = null; private Button btn5 = null; private Button btn6 = null; private TextView tv = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout layout = new LinearLayout(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(250, 50); layout.setOrientation(LinearLayout.VERTICAL); btn1 = new Button(this); btn1.setId(101); btn1.setText("message from main thread self"); btn1.setOnClickListener(this); layout.addView(btn1, params); btn2 = new Button(this); btn2.setId(102); btn2.setText("message from other thread to main thread"); btn2.setOnClickListener(this); layout.addView(btn2,params); btn3 = new Button(this); btn3.setId(103); btn3.setText("message to other thread from itself"); btn3.setOnClickListener(this); layout.addView(btn3, params); btn4 = new Button(this); btn4.setId(104); btn4.setText("message with Runnable as callback from other thread to main thread"); btn4.setOnClickListener(this); layout.addView(btn4, params); btn5 = new Button(this); btn5.setId(105); btn5.setText("main thread's message to other thread"); btn5.setOnClickListener(this); layout.addView(btn5, params); btn6 = new Button(this); btn6.setId(106); btn6.setText("exit"); btn6.setOnClickListener(this); layout.addView(btn6, params); tv = new TextView(this); tv.setTextColor(Color.WHITE); tv.setText(""); params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT); params.topMargin=10; layout.addView(tv, params); setContentView(layout); receiveMessageThread = new ReceiveMessageThread(); receiveMessageThread.start(); } class EventHandler extends Handler{ public EventHandler(Looper looper){ super(looper); } public EventHandler(){ super(); } @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Log.e(TAG, "CurrentThread id:----------+>" + Thread.currentThread().getId()); switch(msg.what){ case 1: tv.setText((String)msg.obj); break; case 2: tv.setText((String)msg.obj); noLooperThread.stop(); break; case 3: //不能在非主線程的線程裏面更新UI,因此這裏經過log打印信息 Log.e(TAG,(String)msg.obj); ownLooperThread.stop(); break; default: Log.e(TAG,(String)msg.obj); break; } } } //ReceiveMessageThread has his own message queue by execute Looper.prepare(); class ReceiveMessageThread extends Thread { @Override public void run(){ Looper.prepare(); mOtherThreadHandler= new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Log.e(TAG,"-------+>"+(String)msg.obj); Log.e(TAG, "CurrentThread id:----------+>" + Thread.currentThread().getId()); } }; Log.e(TAG, "ReceiveMessageThread id:--------+>" + this.getId()); Looper.loop(); } } class NoLooperThread extends Thread { private EventHandler mNoLooperThreadHandler; @Override public void run() { Looper myLooper = Looper.myLooper(); Looper mainLooper= Looper.getMainLooper(); String msgobj; if(null == myLooper){ //這裏得到的是主線程的Looper,因爲NoLooperThread沒有本身的looper因此這裏確定會被執行 mNoLooperThreadHandler = new EventHandler(mainLooper); msgobj = "NoLooperThread has no looper and handleMessage function executed in main thread!"; } else{ mNoLooperThreadHandler = new EventHandler(myLooper); msgobj = "This is from NoLooperThread self and handleMessage function executed in NoLooperThread!"; } mNoLooperThreadHandler.removeMessages(0); if(bpostRunnable == false){ //send message to main thread Message msg = mNoLooperThreadHandler.obtainMessage(2, 1, 1, msgobj); mNoLooperThreadHandler.sendMessage(msg); Log.e(TAG, "NoLooperThread id:--------+>" + this.getId()); }else{ //下面new出來的實現了Runnable接口的對象中run函數是在Main Thread中執行,不是在NoLooperThread中執行 記得 null == myLooper麼 //注意Runnable是一個接口,它裏面的run函數被執行時不會再新建一個線程 //您能夠在run上加斷點而後在eclipse調試中看它在哪一個線程中執行 mNoLooperThreadHandler.post(new Runnable(){ public void run() { // TODO Auto-generated method stub tv.setText("update UI through handler post runnalbe mechanism!"); Log.e(TAG, "update UI id:--------+>" + Thread.currentThread().getId()); noLooperThread.stop(); } }); } } } class OwnLooperThread extends Thread{ private EventHandler mOwnLooperThreadHandler = null; @Override public void run() { Looper.prepare(); Looper myLooper = Looper.myLooper(); Looper mainLooper= Looper.getMainLooper(); String msgobj; if(null == myLooper){ mOwnLooperThreadHandler = new EventHandler(mainLooper); msgobj = "OwnLooperThread has no looper and handleMessage function executed in main thread!"; }else{ mOwnLooperThreadHandler = new EventHandler(myLooper); msgobj = "This is from OwnLooperThread self and handleMessage function executed in NoLooperThread!"; } mOwnLooperThreadHandler.removeMessages(0); //給本身發送消息 Message msg = mOwnLooperThreadHandler.obtainMessage(3,1,1,msgobj); mOwnLooperThreadHandler.sendMessage(msg); Looper.loop(); } } public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()){ case 101: //主線程發送消息給本身 Looper looper = Looper.myLooper();//get the Main looper related with the main thread //若是不給任何參數的話會用當前線程對應的Looper(這裏就是Main Looper)爲Handler裏面的成員mLooper賦值 mHandler = new EventHandler(looper); // 清除整個MessageQueue裏的消息 mHandler.removeMessages(0); String obj = "This main thread's message and received by itself!"; Message msg = mHandler.obtainMessage(1,1,1,obj); // 將Message對象送入到main thread的MessageQueue裏面 mHandler.sendMessage(msg); break; case 102: //other線程發送消息給主線程 bpostRunnable = false; noLooperThread = new NoLooperThread(); noLooperThread.start(); break; case 103: //other thread獲取它本身發送的消息 tv.setText("please look at the error level log for other thread received message"); ownLooperThread = new OwnLooperThread(); ownLooperThread.start(); break; case 104: //other thread經過Post Runnable方式發送消息給主線程 bpostRunnable = true; noLooperThread = new NoLooperThread(); noLooperThread.start(); break; case 105: //主線程發送消息給other thread if(null!=mOtherThreadHandler){ tv.setText("please look at the error level log for other thread received message from main thread"); String msgObj = "message from mainThread"; Message mainThreadMsg = mOtherThreadHandler.obtainMessage(1, 1, 1, msgObj); mOtherThreadHandler.sendMessage(mainThreadMsg); } break; case 106: finish(); break; } } }