原地址:http://www.eoeandroid.com/thread-72298-1-1.html
Handler基本概念:
Handler主要用於非同步訊息的處理:當發出一個訊息之後,首先進入一個訊息佇列,發送訊息的函數即刻返回,而另外一個部分逐個的在訊息佇列中將訊息取出,然後對訊息進行出來,就是發送訊息和接收訊息不是同步的處理。 這種機制通常用來處理相對耗時比較長的操作。
使用一個例子簡單的來介紹一下Handler。
樣本1:一個應用程式中有2個按鈕(start、end),當點擊start按鈕時,執行一個線程,這個線程在控制台輸出一串字串,並且每隔3秒再執行一次線程,直到點擊end按鈕為止,線程停止。
為這個應用程式的介面:
為執行程式時控制台的輸出:
開發步驟:
1、 建立一個Android應用程式
2、 在布局檔案中添加2個Button控制項標籤,並為其設定屬性和值
3、 在Activity中,聲明控制項變數並根據id獲得控制項對象
4、 在Activity中,建立一個Handler對象
5、 在Activity中,建立一個Runnable對象
a) 以匿名內部類的方式
b) 將要執行的操作寫在Runnable對象中的run()方法中
i. 列印出一句話
ii. 調用Runnable對象的postDelayed()方法
6、 在Activity中,編寫start按鈕需要的監聽器,並綁定
a) 在這個監聽器的Onclick()方法中,調用Handler的post()方法,將要執行的線程對象放到隊列當中。
7、 在Activity中,編寫end按鈕需要的監聽器,並幫定
a) 在這個監聽器的Onclick()方法中,調用Handler的removeCallbacks ()方法,刪除隊列當中未執行的線程對象。
b)
下面是Activity的代碼:
package eoe.demo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class HandlerTest extends Activity {
/** Called when the activity is first created. */
private Button startButton;
private Button endButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//根據id獲得控制項對象
startButton = (Button)findViewById(R.id.startButton);
endButton = (Button)findViewById(R.id.endButton);
//為控制項設定監聽器
startButton.setOnClickListener(new StartButtonListener());
endButton.setOnClickListener(new EndButtonListener());
}
class StartButtonListener implements OnClickListener{
public void onClick(View v) {
//調用Handler的post()方法,將要執行的線程對象放到隊列當中
handler.post(updateThread);
}
}
class EndButtonListener implements OnClickListener{
public void onClick(View v) {
//調用Handler的removeCallbacks()方法,刪除隊列當中未執行的線程對象
handler.removeCallbacks(updateThread);
}
}
//建立Handler對象
Handler handler = new Handler();
//建立一個線程對象
Runnable updateThread = new Runnable(){
//將要執行的操作寫線上程對象的run方法當中
public void run(){
System.out.println("updateThread");
//調用Handler的postDelayed()方法
//這個方法的作用是:將要執行的線程對象放入到隊列當中,待時間結束後,運行制定的線程對象
//第一個參數是Runnable類型:將要執行的線程對象
//第二個參數是long類型:延遲的時間,以毫秒為單位
handler.postDelayed(updateThread, 3000);
}
};
}
上面是一個最簡單的例子,下面再看另外一個例子。
樣本2:一個應用程式中有一個進度條和一個按鈕,當點擊按鈕後,每隔一秒鐘進度條前進一部分。
為應用程式的運行:
開發步驟:
1、 建立一個Android應用程式
2、 在布局檔案中添加一個progressBar和一個Button,並為其設定屬性和值
3、 在Activity中,聲明控制項變數並根據id獲得控制項對象
4、 建立線程對象
a) 通過匿名內部類的方式
b) 在編寫完了5、6步之後再來繼續編寫這個線程對象裡的操作
i. 聲明一個變數用來設定進度條的進度
ii. 重寫線程類的run方法(),裡面編寫要執行的操作
1. 列印一個字串
2. 進度條的值增加
3. 得到一個訊息對象
4. 設定訊息對象arg1的值
5. 讓線程休眠一秒鐘
6. 將訊息對象放入到訊息佇列中
7. 判斷,如果進度條的值等於100,則將線程對象從隊列中移除。
5、 建立Handler對象
a) 與樣本1不同的地方是,這裡是通過匿名內部類的方式來聲明的,而樣本1是直接new出來的對象
b) 重寫Handler對象的handlerMessage(Message msg)方法
i. 這個方法傳入了一個Message對象,即訊息對象,首先設定進度條的進度(這個值是Messag對象裡面的一個成員變數arg1)。
ii. 將要執行的線程對象放入到隊列當中
6、 編寫Button需要的監聽器,並綁定
a) 設定進度條為顯示狀態
b) 將要執行的線程對象放入到隊列當中
package eoe.demo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
public class ProgressBarHandlerTest extends Activity {
/** Called when the activity is first created. */
private ProgressBar progressBar;
private Button startButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
progressBar = (ProgressBar)findViewById(R.id.progressbar);
startButton = (Button)findViewById(R.id.startButton);
startButton.setOnClickListener(new ProgressBarOnClickListener());
}
class ProgressBarOnClickListener implements OnClickListener{
public void onClick(View v) {
//設定進度條為可見狀態
progressBar.setVisibility(View.VISIBLE);
updateBarHandler.post(updateThread);
}
}
//使用匿名內部類來複寫Handler當中的handlerMessage()方法
Handler updateBarHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
progressBar.setProgress(msg.arg1);
updateBarHandler.post(updateThread); //將要執行的線程放入到隊列當中
}
};
//線程類,該類使用匿名內部類的方式進行聲明
Runnable updateThread = new Runnable(){
int i = 0;
public void run() {
// TODO Auto-generated method stub
System.out.println("Begin Thread");
i+=10;
//得到一個訊息對象,Message類是android系統提供的
Message msg = updateBarHandler.obtainMessage();
//將Message對象的arg1參數的值設定為i
msg.arg1 = i; //用arg1、arg2這兩個成員變數傳遞訊息,優點是系統效能消耗較少
try{
Thread.sleep(1000); //讓當前線程休眠1000毫秒
}catch(InterruptedException ex){
ex.printStackTrace();
}
//將Message對象加入到訊息佇列當中
updateBarHandler.sendMessage(msg);
//如果i的值等於100
if (i == 100){
//將線程對象從隊列中移除
updateBarHandler.removeCallbacks(updateThread);
}
}
};
}