我們進行Android開發時,Handler可以說是使用非常頻繁的一個概念,它的用處不言而喻。本文就詳細介紹Handler的基本概念和用法。
Handler的基本概念
Handler主要用於異步消息的處理:當發出一個消息之後,首先進入一個消息隊列,發送消息的函數即刻返回,而另外一個部分逐個的在消息隊列中將消息取出,然後對消息進行出來,就是發送消息和接收消息不是同步的處理。 這種機制通常用來處理相對耗時比較長的操作。
Handler工具類在多線程中有兩方面的應用:
1、發送消息,在不同的線程間發送消息,使用的方法為sendXXX();。
android.os.Handler對象通過下面的方法發送消息的:
sendEmptyMessage(int),發送一個空的消息;
sendMessage(Message),發送消息,消息中可以攜帶參數;
sendMessageAtTime(Message, long),未來某一時間點發送消息;
sendMessageDelayed(Message, long),延時Nms發送消息。
2、計劃任務,在未來執行某任務,使用的方法為postXXX();。
android.os.Handler對象通過下面的方法執行計劃任務:
post(Runnable),提交計劃任務馬上執行;
postAtTime(Runnable, long),提交計劃任務在未來的時間點執行;
postDelayed(Runnable, long),提交計劃任務延時Nms執行。
使用一個例子簡單的來介紹一下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按鈕需要的監聽器,並綁定。
在這個監聽器的Onclick()方法中,調用Handler的post()方法,將要執行的線程對象放到隊列當中。
7、在Activity中,編寫end按鈕需要的監聽器,並幫定。
在這個監聽器的Onclick()方法中,調用Handler的removeCallbacks ()方法,刪除隊列當中未執行的線程對象。
下面是Activity的代碼:
Java代碼
- package android.handler;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- 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 startButton;
- private Button endButton;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //根據id獲得控件對象
- startButton = (Button)findViewById(R.id.startButton);
- endButton = (Button)findViewById(R.id.endButton);
- //為控件設置監聽器
- startButton.setOnClickListener(new StartButtonListener());
- endButton.setOnClickListener(new EndButtonListener());
- }
-
- class StartButtonListener implements OnClickListener{
- public void onClick(View v) {
- //調用Handler的post()方法,將要執行的線程對象放到隊列當中
- handler.post(updateThread);
- }
- }
-
- class EndButtonListener implements OnClickListener{
- public void onClick(View v) {
- //調用Handler的removeCallbacks()方法,刪除隊列當中未執行的線程對象
- handler.removeCallbacks(updateThread);
- }
-
- }
-
- //創建Handler對象
- Handler handler = new Handler();
- //新建一個線程對象
- Runnable updateThread = new Runnable(){
- //將要執行的操作寫在線程對象的run方法當中
- public void run(){
- System.out.println("updateThread");
- //調用Handler的postDelayed()方法
- //這個方法的作用是:將要執行的線程對象放入到隊列當中,待時間結束後,運行制定的線程對象
- //第一個參數是Runnable類型:將要執行的線程對象
- //第二個參數是long類型:延遲的時間,以毫秒為單位
- handler.postDelayed(updateThread, 3000);
- }
- };
- }
示例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) 將要執行的線程對象放入到隊列當中。
下面是Activity的代碼:
Java代碼
- package android.handler;
-
- 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 ProgressBarHandlerTest extends Activity {
- /** Called when the activity is first created. */
-
- private ProgressBar progressBar;
- private Button startButton;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- progressBar = (ProgressBar)findViewById(R.id.progressbar);
- startButton = (Button)findViewById(R.id.startButton);
-
- startButton.setOnClickListener(new ProgressBarOnClickListener());
- }
-
- class ProgressBarOnClickListener implements OnClickListener{
- public void onClick(View v) {
- //設置進度條為可見狀態
- progressBar.setVisibility(View.VISIBLE);
- updateBarHandler.post(updateThread);
- }
- }
-
- //使用匿名內部類來復寫Handler當中的handlerMessage()方法
- Handler updateBarHandler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- progressBar.setProgress(msg.arg1);
- updateBarHandler.post(updateThread); //將要執行的線程放入到隊列當中
- }
- };
-
- //線程類,該類使用匿名內部類的方式進行聲明
- Runnable updateThread = new Runnable(){
- int i = 0;
- public void run() {
- // TODO Auto-generated method stub
- System.out.println("Begin Thread");
- i+=10;
- //得到一個消息對象,Message類是android系統提供的
- Message msg = updateBarHandler.obtainMessage();
- //將Message對象的arg1參數的值設置為i
- msg.arg1 = i; //用arg1、arg2這兩個成員變量傳遞消息,優點是系統性能消耗較少
- try{
- Thread.sleep(1000); //讓當前線程休眠1000毫秒
- }catch(InterruptedException ex){
- ex.printStackTrace();
- }
- //將Message對象加入到消息隊列當中
- updateBarHandler.sendMessage(msg);
- //如果i的值等於100
- if (i == 100){
- //將線程對象從隊列中移除
- updateBarHandler.removeCallbacks(updateThread);
- }
- }
- };
- }