當用戶點擊一個按鈕時如果執行的是一個常耗時操作的話,處理不好會導致系統假死,用戶體驗很差,而Android則更進一步,如果任意一個Acitivity沒有響應5秒鐘以上就會被強制關閉,因此我們需要另外起動一個線程來處理長耗時操作,而主線程則不受其影響,在耗時操作完結發送消息給主線程,主線程再做相應處理。那麼線程之間的消息傳遞和異步處理用的就是Handler。
下面我們通過一個模擬文件下載的這個長耗時操作來做個說明:
1、新建一個項目Lesson27_Handler。
2、在MainHandler.java中寫如下面內容:
Java代碼
- package android.basic.lesson27;
-
- import android.app.Activity;
- import android.app.ProgressDialog;
- import android.content.res.Resources;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
-
- public class MainHandler extends Activity {
-
- //聲明變量
- private Button b1;
- private ProgressDialog pd;
-
- //定義Handler對象
- private Handler handler =new Handler(){
- @Override
- //當有消息發送出來的時候就執行Handler的這個方法
- public void handleMessage(Message msg){
- super.handleMessage(msg);
- //只要執行到這裡就關閉對話框
- pd.dismiss();
- }
- };
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- Resources res= this.getResources();
- //查看UI組件所在的線程名
- Log.i("tag", "onCreate()-->"+Thread.currentThread().getName());
-
- //定義UI組件
- b1= (Button)findViewById(R.id.Button01);
- //給按鈕綁定單擊事件監聽器
- b1.setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(View v) {
- //點擊按鈕後去處理長耗時操作
- processThread();
- }
- });
- }
-
- private void processThread(){
-
- //構建一個下載進度條
- pd= ProgressDialog.show(MainHandler.this, "下載文件", "正在下載……");
- Log.i("tag", "processThread()-->"+Thread.currentThread().getName());
-
- new Thread(){
-
- @Override
- public void run(){
- Log.i("tag", "run()-->"+Thread.currentThread().getName());
- //在新線程裡執行長耗時方法
- longTimeMethod();
- //執行完畢後給handler發送一個空消息
- handler.sendEmptyMessage(0);
- }
-
- }.start();
- }
-
- //模擬下載文件的長耗時方法
- private void longTimeMethod(){
- try {
- Log.i("tag", "longTimeMethod-->"+Thread.currentThread().getName());
- Thread.sleep(10000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
3、res/layout/main.xml的內容就省略了,你們可以根據程序運行截圖和程序代碼反推出來布局組件。
4、運行程序查看結果:
這個例子裡,在輔助線程的run方法中執行長耗時操作,操作完畢後調用handler.sendEmptyMessage()方法,主線程中的Handler的 handleMessage()方法接受到這一消息,並做了就是關閉對話框的處理。