Android學習筆記48:使用Handler實時更新UI


  在Android中,主要通過MessageQueue、Looper和Handler三個類來實現Android應用程序的消息處理。其中,MessageQueue類用來描述消息隊列;Looper類用來創建消息隊列,以及進入消息循環;Handler類則用來發送消息和接收消息。

  本文將主要對Handler進行簡要介紹,並以一個簡單的實例演示如何使用Handler實時更新UI。

 

1.Handler的作用

  在Android中,當應用程序啟動時,Android系統會啟動一個主線程(也被稱為UI線程),主要用來管理界面中的UI控件,對用戶操作進行實時響應。如果我們在UI線程中進行一項非常耗時的操作,比如點擊Button按鈕,進行文件上傳或下載,那么在這段時間內界面會出現假死現象(不響應用戶操作),這顯然是用戶體驗極差的。更為嚴重的是,如果在5秒內這個耗時的操作還未結束的話,Android系統會進行錯誤提示“強制關閉”。

  所以通常的做法是啟動一個子線程,然后在子線程中來完成這些比較耗時的操作。但是,如果我們想要在子線程中更新UI,那又該如何做呢?

  因為在Android中,更新UI只可以在主線程中進行,所以想要在子線程中更新UI,就必須得子線程通知主線程,然后主線程來更新UI。

  這一過程正是通過Handler來實現的。

  子線程可以通過兩種方式與Handler進行通信:Message和Runnable。使用Message可以從子線程中傳遞一些參數給主線程,Handler獲取這些信息並進行相應的處理。使用Runnable則可以直接執行某個處理結果。其實,這兩者的實質都是在Handler的隊列中放入內容,Handler會處理完一個消息或者執行完某個處理之后再進行下一步操作,這樣就不會出現多個線程同時要求進行UI處理而引發混亂現象。 

 

2.Handler的常用方法

  Handler的消息隊列中的內容(Message或Runnable)可以設置為馬上執行,延遲一定時間再執行或者指定在某個時刻執行。此外,還可以指定將其放在隊列的頭部,表示該內容具有最高優先級別,立刻執行。

  這些要求的設置可以通過以下一些函數來實現:

  (1)post(Runnable r);

  (2)postAtTime(Runnable r, long uptimeMillis);

  (3)postDelayed(Runnable r, long uptimeMillis);

  (4)postAtFrontOfQueue(Runnable r);

  (5)sendEmptyMessage(int what);

  (6)sendMessage(Message msg);

  (7)sendMessageAtTime(Message msg, long uptimeMillis);

  (8)sendMessageDelayed(Message msg, long uptimeMillis);

  (9)sendMessageAtFrontOfQueue(Runnable r); 

 

3.實例

  在本實例中,我們創建了一個Web工程,該Web工程很簡單,僅僅是獲取系統的當前時間,然后顯示出來而已。

  在Tomcat上運行該Web工程,能夠看到如圖1所示的運行效果。

圖1 Web工程運行效果

  該頁面是通過一個簡單的date.jsp文件來實現的。

  我們現在要做的就是,在Android工程中,通過一個TextView來顯示當前頁面的內容,並且在子線程中每隔1秒鍾,發送一個Message給Handler,Handler收到Message通知后,完成刷新UI的操作。

  下面就來說說每一步的具體實現。

3.1在主線程中啟動一個子線程

  首先,我們需要在主線程中啟動一個子線程,這個比較簡單,直接在MainActivity的onCreate()方法中調用如下方法即可:

  new Thread(mRunnable).start();

3.2在子線程中發送Message給Handler

  在創建子線程時,我們使用了Runnable接口對象mRunnable。這里,只需要實現Runnable接口,並重寫該接口的run()方法,在run()方法中實現每1秒發送一條Message給Handler即可。具體實現方法如下:

 1     /*
 2      * Function   :   實現run()方法,每1秒發送一條Message給Handler
 3      * Author     :   博客園-依舊淡然
 4      */
 5     private Runnable mRunnable = new Runnable() {
 6         public void run() {
 7             while(true) {
 8                 try {
 9                     Thread.sleep(1000);
10                     mHandler.sendMessage(mHandler.obtainMessage());
11                 } catch (InterruptedException e) {
12                     e.printStackTrace();
13                 }
14             }
15         }
16     };

 3.3Handler接收Message通知

  最后,我們創建一個Handler對象,用來接收Message通知。在收到Message通知后,完成刷新UI的操作即可。具體實現方法如下:

 1     /*
 2      * Function   :   實現handleMessage()方法,用於接收Message,刷新UI
 3      * Author     :   博客園-依舊淡然
 4      */
 5     private Handler mHandler = new Handler() {
 6         public void handleMessage(Message msg) {
 7             super.handleMessage(msg);
 8             refreshUI();
 9         }
10     };

 3.4刷新UI

  由以上的代碼可以看出,刷新UI的操作,我們是放在refreshUI()方法中來完成的。refreshUI()方法的實現也很簡單,調用HttpUtils工具類中的getInputStream()方法,獲得圖1所示Web工程的頁面內容輸入流,再將該輸入流轉化為字符串,放入TextView控件中進行顯示即可。具體實現方法如下:

 1     /*
 2      * Function   :   刷新UI
 3      * Author     :   博客園-依舊淡然
 4      */
 5     private void refreshUI() {
 6         try {
 7             InputStream inputStream = HttpUtils.getInputStream();
 8             String resultData = HttpUtils.getResultData(inputStream);
 9             mTextView.setText(resultData);
10         } catch (IOException e) {
11             e.printStackTrace();
12         }
13     }

 3.5實例效果

  最后,運行該Android工程,運行效果如圖2所示,可以看到,當前時間每隔1秒會刷新一次,能夠始終保持與圖1所示頁面的時間同步。

 

圖2 運行效果

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM