Android之handler講解

  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的代碼:

Java代碼:

  1. package eoe.demo;

  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;

  8. public class HandlerTest extends Activity {
  9. /** Called when the activity is first created. */
  10. private Button startButton;
  11. private Button endButton;

  12. @Override
  13. public void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.main);
  16. //根據id獲得控件對象
  17. startButton = (Button)findViewById(R.id.startButton);
  18. endButton = (Button)findViewById(R.id.endButton);
  19. //爲控件設置監聽器
  20. startButton.setOnClickListener(new StartButtonListener());
  21. endButton.setOnClickListener(new EndButtonListener());
  22. }

  23. class StartButtonListener implements OnClickListener{
  24. public void onClick(View v) {
  25. //調用Handler的post()方法,將要執行的線程對象放到隊列當中
  26. handler.post(updateThread);
  27. }
  28. }

  29. class EndButtonListener implements OnClickListener{
  30. public void onClick(View v) {
  31. //調用Handler的removeCallbacks()方法,刪除隊列當中未執行的線程對象
  32. handler.removeCallbacks(updateThread);
  33. }

  34. }

  35. //創建Handler對象
  36. Handler handler = new Handler();
  37. //新建一個線程對象
  38. Runnable updateThread = new Runnable(){
  39. //將要執行的操作寫在線程對象的run方法當中
  40. public void run(){
  41. System.out.println("updateThread");
  42. //調用Handler的postDelayed()方法
  43. //這個方法的作用是:將要執行的線程對象放入到隊列當中,待時間結束後,運行制定的線程對象
  44. //第一個參數是Runnable類型:將要執行的線程對象
  45. //第二個參數是long類型:延遲的時間,以毫秒爲單位
  46. handler.postDelayed(updateThread, 3000);
  47. }
  48. };
  49. }
複製代碼

       上面是一個最簡單的例子,下面再看另外一個例子。
       示例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) 將要執行的線程對象放入到隊列當中

Java代碼:

  1. package eoe.demo;

  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.os.Message;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.widget.Button;
  9. import android.widget.ProgressBar;

  10. public class ProgressBarHandlerTest extends Activity {
  11. /** Called when the activity is first created. */

  12. private ProgressBar progressBar;
  13. private Button startButton;

  14. @Override
  15. public void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.main);

  18. progressBar = (ProgressBar)findViewById(R.id.progressbar);
  19. startButton = (Button)findViewById(R.id.startButton);

  20. startButton.setOnClickListener(new ProgressBarOnClickListener());
  21. }

  22. class ProgressBarOnClickListener implements OnClickListener{
  23. public void onClick(View v) {
  24. //設置進度條爲可見狀態
  25. progressBar.setVisibility(View.VISIBLE);
  26. updateBarHandler.post(updateThread);
  27. }
  28. }

  29. //使用匿名內部類來複寫Handler當中的handlerMessage()方法
  30. Handler updateBarHandler = new Handler(){
  31. @Override
  32. public void handleMessage(Message msg) {
  33. progressBar.setProgress(msg.arg1);
  34. updateBarHandler.post(updateThread); //將要執行的線程放入到隊列當中
  35. }
  36. };

  37. //線程類,該類使用匿名內部類的方式進行聲明
  38. Runnable updateThread = new Runnable(){
  39. int i = 0;
  40. public void run() {
  41. // TODO Auto-generated method stub
  42. System.out.println("Begin Thread");
  43. i+=10;
  44. //得到一個消息對象,Message類是android系統提供的
  45. Message msg = updateBarHandler.obtainMessage();
  46. //將Message對象的arg1參數的值設置爲i
  47. msg.arg1 = i; //用arg1、arg2這兩個成員變量傳遞消息,優點是系統性能消耗較少
  48. try{
  49. Thread.sleep(1000); //讓當前線程休眠1000毫秒
  50. }catch(InterruptedException ex){
  51. ex.printStackTrace();
  52. }
  53. //將Message對象加入到消息隊列當中
  54. updateBarHandler.sendMessage(msg);
  55. //如果i的值等於100
  56. if (i == 100){
  57. //將線程對象從隊列中移除
  58. updateBarHandler.removeCallbacks(updateThread);
  59. }
  60. }
  61. };
  62. }
複製代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章