在android中,有很多功能是不能放在onCreate或者onStart方法裡面,因為這些功能相對
來說費時比較長,比如說下載一個檔案,下載的過程比較長,但是如果寫在Activity中,
那麼這段時間Activity是完全沒有響應的,那麼就可以將這種處理大量資料或者耗時比較
長的東西放在一個單獨的執行緒中來完成,即Activity是一個執行緒,而下載的是在另外一個
執行緒,那麼這樣就可以使得下載跟Activity之間互不影響,從而得到了良好的使用者體驗
這裡有兩種佇列,一種是執行緒佇列,就是用postXX方法或者removeCallbacks方法對執行緒物件的操作。另一種是訊息佇列,用sendMessage和handleMessage方法來對訊息物件進行處理
handler採用的是一個訊息佇列的方式,每一個handler都有一個與之關聯的訊息佇列,而且是先進先出的方式執行,即:每次加入一個handler,然後拿出來,對其進行處理,然後再拿出另一個,再進行處理
例子一:這個例子僅僅是對執行緒物件進行操作的測試
package org.hualang.handler; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.Button; public class HandlerTest extends Activity { private Button mybutton1; private Button mybutton2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mybutton1 = (Button)findViewById(R.id.mybutton1); mybutton2 = (Button)findViewById(R.id.mybutton2); mybutton1.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View arg0) { /** * 呼叫Handler的post方法,將要執行的執行緒物件新增到 * 執行緒佇列中 */ handler.post(updateThread); } }); mybutton2.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub handler.removeCallbacks(updateThread); } }); } //建立Handler物件 Handler handler = new Handler(); /** * 將要執行的操作解除安裝寫入執行緒物件的run()方法當中 */ Runnable updateThread = new Runnable() { public void run() { System.out.println("更新執行緒"); //在run方法內部,執行postXX的方法,每隔3秒會執行一次 handler.postDelayed(updateThread, 3000); } }; }
程式解釋:首先建立一個Handler物件,然後建立一個繼承自Runnable介面的執行緒
程式首先點選按鈕“開始”,於是會馬上執行post方法,將執行的執行緒物件新增到執行緒佇列中,這時會馬上執行
public void run() { System.out.println("更新執行緒"); //在run方法內部,執行postXX的方法,每隔3秒會執行一次 handler.postDelayed(updateThread, 3000); }
然後,執行postDelayed方法,由於裡面設定的間隔時間,所以每3秒會調價一個handler物件到執行緒佇列中,並且一直執行,直到點選“結束”按鈕,呼叫removeCallbacks方法將其從執行緒佇列中移除
例子2:下面的例子將簡單的對執行緒物件和訊息物件進行處理
package org.hualang.handlertest2; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.ProgressBar; public class HandlerTest2 extends Activity { private ProgressBar bar = null; private Button start = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); bar = (ProgressBar)findViewById(R.id.progress1); start = (Button)findViewById(R.id.start); start.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { bar.setVisibility(View.VISIBLE); handler.post(handlerThread); } }); } /** * 使用匿名內部類來複寫hanlder當中的hanldrMessage方法 * 這裡的msg物件就是從執行緒部分傳送過來的物件 */ Handler handler = new Handler() { public void handleMessage(Message msg) { bar.setProgress(msg.arg1); handler.post(handlerThread); } }; //執行緒類,該類使用的是匿名內部類的方式進行宣告 Runnable handlerThread = new Runnable() { int i = 0; public void run() { System.out.println("開始執行緒"); i = i + 10; /** * 得到一個訊息物件,Message類是由android作業系統提供 * obtainMessage方法用來得到Message物件 */ Message msg = handler.obtainMessage(); /** * Message中有個成員變數,即msg獨享的arg1引數 * 將其值設定為i。用arg1或arg2這兩個成員變數傳遞 * 訊息,優點是系統效能消耗較少 */ msg.arg1 = i; try { //當前執行緒休眠1秒 Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } /** * 傳送一個訊息,用sendMessage是將msg加入到訊息 * 佇列中。而post是將執行緒加入到執行緒佇列中 */ handler.sendMessage(msg); if( i == 100) { /** * 如果i=100的時候,就將執行緒物件 * 從handler當中移除 */ handler.removeCallbacks(handlerThread); bar.setVisibility(View.GONE); } } }; }
<?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" > <ProgressBar android:id="@+id/progress1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:visibility="gone" style="?android:attr/progressBarStyleHorizontal" /> <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="點選我" /> </LinearLayout>
程式說明:
1、當點選按鈕後,會執行按鈕的onClick方法中的
bar.setVisibility(View.VISIBLE);
handler.post(handlerThread);
將進度條顯示出來,並且將執行緒物件加入到執行緒佇列中
2、執行緒物件對先列印出一個“開始執行緒”,然後i的值增加10,然後從系統中獲取一個Message物件
3、將i賦給Message物件的引數arg1
4、當前執行緒休眠5秒,然後通過sendMessage方法傳送一個Message物件傳送到訊息佇列中
5、然後再執行,通過handleMessage方法設定進度條的值,並且將其加入到程式佇列中
Handler handler = new Handler() { public void handleMessage(Message msg) { bar.setProgress(msg.arg1); handler.post(handlerThread); } };
6、迴圈執行,直到i=100,進度條隱藏,並將執行緒物件從執行緒佇列中取出
原文:http://www.iteye.com/topic/1062942