Android學習筆記06——handler的使用

GeekWay發表於2012-02-14

一、          Handler的基本概念

Handler主要用於非同步訊息的處理:當發出一個訊息之後,首先進入一個訊息隊列,傳送訊息的函式即刻返回,而另外一個部分逐個的在訊息佇列中將訊息取出,然後對訊息進行出來,就是傳送訊息和接收訊息不是同步的處理。(通常情況下,都是執行緒。將訊息取出就是執行執行緒的run方法)

這種機制通常用來處理相對耗時比較長的操作。如下載檔案等。



一個Handler物件對應一個訊息佇列。

二、          使用一個例子簡單的來介紹一下Handler

示例1:一個應用程式中有2個按鈕(startend),當點選start按鈕時,執行一個執行緒,這個執行緒在控制檯輸出一串字串,並且每隔3秒再執行一次執行緒,直到點選end按鈕為止,執行緒停止。

下圖為這個應用程式的介面:


Main.xml

<Button

       android:id="@+id/start"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:text="開始"/>

 

   <Button

       android:id="@+id/end"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:text="結束"/>

java檔案中

publicclassHandlerTestextendsActivity {

   

   privateButtonstartButton;

   privateButtonendButton;

   

   @Override

   publicvoidonCreate(Bundle savedInstanceState){

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

       //根據id獲得控制元件物件

       startButton=(Button)findViewById(R.id.start);

       endButton=(Button)findViewById(R.id.end);

       //為控制元件設定監聽器

       startButton.setOnClickListener(newStartButtonListener());

       endButton.setOnClickListener(newEndButtonListener());

   }

   

   classStartButtonListenerimplementsOnClickListener{

      publicvoidonClick(View v) {

          //呼叫Handlerpost()方法,將要執行的執行緒物件放到佇列當中

          handler.post(updateThread);

      }

   }

   

   classEndButtonListenerimplementsOnClickListener{

      publicvoidonClick(View v) {

          //呼叫HandlerremoveCallbacks()方法,刪除佇列當中未執行的執行緒物件

          handler.removeCallbacks(updateThread);

      }

   

   }

   

   //建立Handler物件

   Handlerhandler= newHandler();

   //新建一個執行緒物件

   RunnableupdateThread= newRunnable(){

   //將要執行的操作寫線上程物件的run方法當中

   publicvoidrun(){

      System.out.println("updateThread");

      //呼叫HandlerpostDelayed()方法

         //這個方法的作用是:將要執行的執行緒物件放入到佇列當中,待時間結束後,執行制定的執行緒物件

         //第一個引數是Runnable型別:將要執行的執行緒物件

         //第二個引數是long型別:延遲的時間,以毫秒為單位

      handler.postDelayed(updateThread, 3000);

   }

   };

}

我的理解總結一下:

1)       首先,建立一個Handler物件

2)       在某一個監聽事件中,利用post方法將執行緒加入訊息佇列

3)       將要執行的操作,寫線上程物件的run方法中


三、  示例2:一個應用程式中有一個進度條和一個按鈕,當點選按鈕後,每隔一秒鐘進度條前進一部分。
下圖為應用程式的執行效果圖:


(注:這裡用到了兩個佇列。)

 

publicclassProgressBarHandlerTestextendsActivity {

   

   

   privateProgressBarprogressBar;

   privateButtonstartButton;

   

   @Override

   publicvoidonCreate(Bundle savedInstanceState){

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

       

       progressBar=(ProgressBar)findViewById(R.id.progressbar);

       startButton=(Button)findViewById(R.id.startButton);

       

       startButton.setOnClickListener(newProgressBarOnClickListener());

   }

   

   classProgressBarOnClickListenerimplementsOnClickListener{

      publicvoidonClick(View v) {

          //設定進度條為可見狀態

          progressBar.setVisibility(View.VISIBLE);

          updateBarHandler.post(updateThread);

      }

   }

   

   //使用匿名內部類來複寫Handler當中的handlerMessage()方法

   HandlerupdateBarHandler= newHandler(){

      @Override

      publicvoidhandleMessage(Message msg){

          progressBar.setProgress(msg.arg1);

          updateBarHandler.post(updateThread);  //將要執行的執行緒放入到佇列當中

      }

   };

   

   //執行緒類,該類使用匿名內部類的方式進行宣告

   RunnableupdateThread= newRunnable(){

   inti= 0;

      publicvoidrun() {

          //TODOAuto-generated method stub

          System.out.println("Begin Thread");

          i+=10;

          //得到一個訊息物件,Message類是android系統提供的

          Message msg =updateBarHandler.obtainMessage();

          //Message物件的arg1引數的值設定為i

          msg.arg1=i;//arg1arg2這兩個成員變數傳遞訊息,優點是系統效能消耗較少

          try{

             Thread.sleep(1000); //讓當前執行緒休眠1000毫秒

          }catch(InterruptedException ex){

             ex.printStackTrace();

          }

          //Message物件加入到訊息佇列當中

          updateBarHandler.sendMessage(msg);

          //如果i的值等於100

          if(i== 100){

             //將執行緒物件從佇列中移除

             updateBarHandler.removeCallbacks(updateThread); 

          }

      }

   };

}

 



相關文章