一、基本概念
在手機使用時,經常碰到這種情況:比如在我們下載的時候,若是將下載方法單獨為一個Activity的時候,那麼下載時,其他的Activity是沒有響應的,那麼這個時候整部手機就處於了當機的狀態,而Handler就是用來解決這個問題的.
意思就是說,將下載放在一個單獨的線程,那麼當這個線程執行的時候,並不會影響該Activity的線程.
二、使用方法
通過調用handler的post方法實現線程的操作.
一個最簡單的Handler例子:
XML檔案:
Java代碼
<span style="font-size: x-small;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1">
<Button
android:id="@+id/start"
android:text="@string/opt_start"
android:layout_height="wrap_content"
android:layout_weight="0.38"
android:layout_width="202dp"/>
<Button
android:layout_height="wrap_content"
android:id="@+id/end"
android:text="@string/opt_end"
android:layout_weight="0.38"
android:layout_width="202dp">
</Button>
</LinearLayout>
</span>
Handler檔案:
Java代碼
<span style="font-size: x-small;">package com.hadler;
import android.accounts.Account;
import android.accounts.OnAccountsUpdateListener;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.text.style.UpdateAppearance;
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 start;
private Button end;
OnClickListener start_listen = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
start = (Button)findViewById(R.id.start);
end = (Button)findViewById(R.id.end);
start_listen = (new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//調用handler的post方法,將要執行的線程對象加到隊列當中
handler.post(updateThread);
}
});
start.setOnClickListener(start_listen);
OnClickListener end_listen = (new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
handler.removeCallbacks(updateThread);
}
});
end.setOnClickListener(end_listen);
}
//建立一個Handler對象
Handler handler = new Handler();
//線程類,實現Runnable介面,將要執行的操作寫在run方法中
Runnable updateThread = new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("UpdateThread");
//在run方法內部,執行postDelayed或者post方法
handler.postDelayed(updateThread, 3000);
}
};
}</span>
這個例子中可看到LogCat中每隔3秒中就列印一句UpdateThread.
即是,不影響當前Acvtivity,調用新的進程完成的程式碼片段. 也就是非同步處理.
三、使用handler更新ProgressBar進度條
接著看一個例子,更新進度條的
Java代碼
<span style="font-size: x-small;"> package mars.barhandler;
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 TestBarHandler extends Activity {
/** Called when the activity is first created. */
//聲明控制項變數
ProgressBar bar = null;
Button startButton = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//根據控制項的ID得到代表控制項的對象,並為按鈕設定監聽器
bar = (ProgressBar)findViewById(R.id.bar);
startButton = (Button)findViewById(R.id.startButton);
startButton.setOnClickListener(new ButtonListener());
}
//當點擊startButton按鈕時,就會執行ButtonListener的onClick方法
class ButtonListener implements OnClickListener{
@Override
//匿名內部類
public void onClick(View v) {
// TODO Auto-generated method stub
//進度條設定為可見的
bar.setVisibility(View.VISIBLE);
//將線程對象updateThread馬上加入到訊息佇列當中,立馬執行線程,執行線程就是執行run方法
updateBarHandler.post(updateThread);
}
}
//使用匿名內部類來複寫Handler當中的handleMessage方法
Handler updateBarHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
//對已經壓入訊息佇列的msg加入到線程隊列裡面
bar.setProgress(msg.arg1)//設定進度條的當前值 <br> Bundle bundle = msg.getData();
updateBarHandler.post(updateThread);
System.out.println("test---->" + bundle.getString("test"));
}
};
//線程類,該類使用匿名內部類的方式進行聲明
Runnable updateThread = new Runnable(){
int i = 0 ;
@Override
public void run() {
System.out.println("Begin Thread" + i);
i = i + 10 ;
//得到一個訊息對象,Message類是由Android作業系統提供
Message msg = updateBarHandler.obtainMessage();
//將msg對象的arg1參數的值設定為i,用arg1和arg2這兩個成員變數傳遞訊息,優點是系統效能消耗較少
msg.arg1 = i ;
Bundle bundle = new Bundle();
bundle.putString("test", "test bundle");
msg.setData(bundle);
try {
//設定當前線程睡眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//將msg對象加入到訊息佇列當中
if( i > 100){
//如果當i的值為100時,就將線程對象從handler當中移除
updateBarHandler.removeCallbacks(updateThread);
System.out.println(">>>>>>");
}else{
//將msg壓入到訊息佇列中,壓入之後就會去執行上面的handleMessage方法
//每次執行完一次壓入,上面代碼就講msg加入線程隊列,只要i小於100,就一直迴圈這個操作
updateBarHandler.sendMessage(msg);
System.out.println("<<<<<<");
}
}
};
class MyThread extends Thread{
public void run(){
}
}
}</span>