Handler 為Android作業系統中的線程通訊工具,包為android.os.Handler。
與Handler綁定的有兩個隊列,一個為訊息佇列,另一個為線程隊列。Handler可以通過這兩個隊列來分別:
- 發送、接受、處理訊息–訊息佇列;
- 啟動、結束、休眠線程–線程隊列;
Android OS中,一個進程被建立之後,主線程(可理解為當前Activity)建立一個訊息佇列,這個訊息佇列維護所有頂層應用對象(Activities, Broadcast receivers等)以及主線程建立的視窗。你可以在主線程中建立新的線程,這些新的線程都通過Handler與主線程進行通訊。通訊通過新線程調用 Handler的post()方法和sendMessage()方法實現,分別對應功能:
- post() 將一個線程加入線程隊列;
- sendMessage() 發送一個訊息對象到訊息佇列;
當然,post()方法還有一些變體,比如postDelayed()、postAtTime()分別用來延遲發送、定時發送;
訊息的處理,在主線程的Handler對象中進行;具體處理過程,需要在new Handler對象時使用匿名內部類重寫Handler的handleMessage(Message msg)方法;
從訊息佇列中擷取訊息。
線程加入線程隊列可以在主線程中也可以在子線程中進行,但都要通過主線程的Handler對象調用post()。
package mars.barhandler;</p><p>import android.app.Activity;<br />import android.os.Bundle;<br />import android.os.Handler;<br />import android.os.Message;<br />import android.view.View;<br />import android.view.View.OnClickListener;<br />import android.widget.Button;<br />import android.widget.ProgressBar;</p><p>public class TestBarHandler extends Activity {<br /> /** Called when the activity is first created. */<br />//聲明控制項變數<br />ProgressBar bar = null;<br />Button startButton = null;<br /> @Override<br /> public void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main);<br /> //根據控制項的ID得到代表控制項的對象,並為按鈕設定監聽器<br /> bar = (ProgressBar)findViewById(R.id.bar);<br /> startButton = (Button)findViewById(R.id.startButton);<br /> startButton.setOnClickListener(new ButtonListener());<br /> }<br /> //當點擊startButton按鈕時,就會執行ButtonListener的onClick方法<br /> class ButtonListener implements OnClickListener{</p><p>public void onClick(View v) {<br />// TODO Auto-generated method stub<br />bar.setVisibility(View.VISIBLE);<br />updateBarHandler.post(updateThread);<br />}</p><p> }<br /> //使用匿名內部類來複寫Handler當中的handleMessage方法<br /> Handler updateBarHandler = new Handler(){</p><p>@Override<br />public void handleMessage(Message msg) {<br />bar.setProgress(msg.arg1);<br />Bundle bundle = msg.getData();<br />updateBarHandler.post(updateThread);<br />System.out.println("test---->" + bundle.getString("test"));<br />}</p><p> };<br /> //線程類,該類使用匿名內部類的方式進行聲明<br /> Runnable updateThread = new Runnable(){<br /> int i = 0 ;<br />public void run() {<br />System.out.println("Begin Thread" + i);<br />i = i + 10 ;<br />//得到一個訊息對象,Message類是有Android作業系統提供<br />Message msg = updateBarHandler.obtainMessage();</p><p>//將msg對象的arg1參數的值設定為i,用arg1和arg2這兩個成員變數傳遞訊息,優點是系統效能消耗較少<br />msg.arg1 = i ;<br />Bundle bundle = new Bundle();<br />bundle.putString("test", "test bundle");<br />msg.setData(bundle);<br />try {<br />//設定當前顯示睡眠1秒<br />Thread.sleep(1000);<br />} catch (InterruptedException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />}<br />//將msg對象加入到訊息佇列當中<br />if( i > 100){<br />//如果當i的值為100時,就將線程對象從handler當中移除<br />updateBarHandler.removeCallbacks(updateThread);<br />System.out.println(">>>>>>");<br />}else{<br />updateBarHandler.sendMessage(msg);<br />System.out.println("<<<<<<");<br />}<br />}<br /> };<br /> class MyThread extends Thread{<br /> public void run(){</p><p> }<br /> }</p><p>}
<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:orientation="vertical"<br /> android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"<br /> ></p><p><ProgressBar<br />android:id="@+id/bar"<br />style="?android:attr/progressBarStyleHorizontal"<br />android:layout_width="200dp"<br />android:layout_height="wrap_content"<br />android:visibility="gone"<br />/><br /><Button<br />android:id="@+id/startButton"<br /> android:layout_width="fill_parent"<br /> android:layout_height="wrap_content"<br /> android:text="start"/><br /></LinearLayout><br />