Handler的常見用法

Handler是Android消息模型最重要的一個概念,它可以說是Android消息模型的核心,對於Looper、MessageQueue、Message 等概念一般在應用中很少使用。在Android系統框架中也頻繁地使用Handler,而且爲了更方便地使用Handler,還把Handler進行了一些列的封裝,下面就通過列舉一些Handler的使用方法。

1)Acitivity的runOnUiThread方法

        使用Acitivity的runOnUiThread方法執行代碼時,可以保證所有的代碼都在UI線程中執行,使用方法如下:

1                 activity.runOnUiThread(new Runnable() {
2                         @Override
3                         public void run() {
4                                 textView.setText("HelloWorld");
5                                 //所有的代碼都會在UI線程中執行
6                         }
7                 });

2)View的post和postDelay方法

        View的post方法與Acitivity的runOnUiThread方法類似,可以保證所有的代碼都在UI線程中執行,View的post方法使用方法如下:
                
1                 view.post((new Runnable() {
2                         @Override
3                         public void run() {
4                                 textView.setText("HelloWorld");
5                                 //所有的代碼都會在UI線程中執行
6                         }
7                 });

        View的postDelay方法與post方法能保證所有的代碼都在UI線程中執行,並且還可以讓代碼延遲一定的時間後執行,View的postDelay方法使用方法如下:

1                 view. postDelay ((new Runnable() {
2                         @Override
3                         public void run() {
4                                 textView.setText("HelloWorld");
5                                 //所有的代碼都會在UI線程中執行
6                         }
7                 }, 1000);// 延遲1秒執行

3)AsyncTask

        AsyncTask是對Android線程模型的一種高度封裝,而且使用java的泛型技術,使用非常方便,而且能夠解決通用問題。在使用AsyncTask類時,需要擴展它並實現以下幾個方法:

public void onPreExecute() 在UI線程中執行,進行以下初始化操作
public Result doInBackground(Params... params) 在後臺線程中執行
public void onProgressUpdate(Progress... values) 在UI線程中執行,通知UI線程更新界面
public void onPostExecute(Result result) 任務結束後,在UI線程中執行
public void onCancelled () 任務取消時,在UI線程中執行

        AsyncTask 使用了Java的泛型技術,所以在使用時需要使用具體的類型,一般的使用方法代碼如下:
 

01 public class UserTask extends AsyncTask < String, Void, Void > {
02         @Override
03         public void onPreExecute() {
04             //初始化操作,在主線程中執行
05         }
06            @Override
07         public Result doInBackground(String... params) {
08            //在後臺線程中執行任務
09         }
10         @Override
11         public void onCancelled() {
12                  //取消任務時的回調
13         }
14         @Override
15         public void onPostExecute() {
16             //任務執行結束時的回調,在主線程中執行
17         }
18 }

        在代碼中使用UserTask時,必須要在UI線程中執行execute方法,代碼如下:

1         new UserTask ().execute(new String [] {“”});

4) IdlerHandler

        使用IdlerHandler可以向當前線程的消息隊列裏發送操作,這些操作之後在空閒的時候纔會執行,它們的優先級非常低。需要注意的是queueIdle的方法可以返回一個布爾值,如果返回false,說明IdleHandler執行一次之後就會被刪除,如果返回true,說明IdleHandler一直是有效的,只要系統處於空閒狀態就執行IdleHandler的queueIdle方法。使用方式如下:
                
1                 Looper.myQueue().addIdleHandler(new IdleHandler() {
2                         @Override
3                         public boolean queueIdle() {
4                                 //系統空閒時進行資源回收操作
5                                 return false;
6                         }
7                 });

5) Handler 

        Handler是Android消息模型最重要的一個組件,使用它可以在線程之間相互發送消息,實現線程之間的通信。處理使用Handler發送消息以外,通常需要繼承Handler類,並重寫handleMessage(Message msg) 方法, 接收消息並處理消息。
下面通過一個實例來說明Handler的使用方法。例子的主要功能是:通過線程修改界面Button的內容,完整的代碼如下:

01 public class MyHandlerActivity extends Activity {
02  
03     Button button;
04     MyHandler myHandler;
05  
06     protected void onCreate(Bundle savedInstanceState) {
07         super.onCreate(savedInstanceState);
08         setContentView(R.layout.handlertest);
09         button = (Button) findViewById(R.id.button);
10         myHandler = new MyHandler();
11         // 當創建一個新的Handler實例時, 它會綁定到當前線程和消息的隊列中,開始分發數據
12         // Handler有兩個作用,
13            //(1) : 定時執行Message和Runnalbe 對象
14         // (2): 讓一個動作,在不同的線程中執行.
15         // 它安排消息,用以下方法
16         // post(Runnable)
17         // postAtTime(Runnable,long)
18         // postDelayed(Runnable,long)
19         // sendEmptyMessage(int)
20         // sendMessage(Message);
21         // sendMessageAtTime(Message,long)
22         // sendMessageDelayed(Message,long)
23         // 以上方法以 post開頭的可以處理Runnable對象
24         //sendMessage()可以處理Message對象(Message裏可以包含數據,)
25         MyThread m = new MyThread();
26         new Thread(m).start();
27     }
28  
29     /**
30     * 接受消息,處理消息 ,此Handler會與當前主線程一塊運行
31     * */
32     class MyHandler extends Handler {
33         
34            //默認構造函數
35            public MyHandler() {
36                   super();
37         }
38          
39            // 帶有Looper參數的構造函數
40            public MyHandler(Looper L) {
41             super(L);
42         }
43         // 子類必須重寫此方法,處理消息
44         @Override
45         public void handleMessage(Message msg) {
46             Log.d("MyHandler""handleMessage......");
47             super.handleMessage(msg);
48             // 此處可以更新UI
49             Bundle b = msg.getData();
50             String color = b.getString("color");
51                    String btn = msg.obj.toString();
52             MyHandlerActivity.this.button.append(color + btn);
53         }
54     }
55  
56     class MyThread implements Runnable {
57         public void run() {
58             try {
59                 Thread.sleep(2000);
60             catch (InterruptedException e) {
61                 // TODO Auto-generated catch block
62                 e.printStackTrace();
63             }
64             Log.d("thread.......""mThread........");
65                    // 使用Message能夠傳遞多種數據具體可以參考Message的源碼
66                    // 最常用的可以使用Message的obj對象在線程之間傳遞對象數據
67             Message msg  =  new Message();
68             Bundle b = new Bundle();// 存放數據
69             b.putString("color""Red");
70             msg.setData(b);
71                    msg.obj = new String(“Button”);
72             MyHandlerActivity.this.myHandler.sendMessage(msg); // 向Handler發送消息,更新UI
73         }
74     }
75 }
6) HandlerThread

        HandlerThread是一個帶有消息循環的線程,並且有自己的消息隊列,能夠接受其他線程發送消息。使用方法Java代碼如下:
                
01                 HandlerThread tt = new HandlerThread("handlerThread");
02                 tt.start();//啓動線程
03                 Handler handler = new Handler(tt.getLooper());
04                 handler.postDelayed(new Runnable() {
05  
06                         @Override
07                         public void run() {
08                                 System.out.println("ThreadName:" + Thread.currentThread().getName());
09                                 ((HandlerThread)Thread.currentThread()).getLooper().quit();//關閉消息循環,退出線程
10                         }
11  
12                 }, 1000);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章