[Android 開發] This message is already in use 解法

Handler 和 Message 是 Android 用來更新畫面的重要方法,有在開發 Android 的朋友都應該要知道這兩個的用法。而海芋最近使用這個方法來開發程式時,碰到了「android.util.AndroidRuntimeException: This message is already in use」這個問題,這是原本的寫法。

  1. private int MSG_INCREASE_PROGRESSBAR = 9527;
  2. private int MSG_Done = 5566;
  3. private ProgressDialog m_progressDialog = null;
  4.  
  5. private Runnable m_runnable = new Runnable(){
  6.   @Override
  7.   public void run() {
  8.     try {
  9.       Message msg = new Message();
  10.       for (int i = 0; i < 100; i++){
  11.         msg.what = MSG_INCREASE_PROGRESSBAR;
  12.         m_Handler.sendMessage(msg);
  13.       }
  14.  
  15.       msg.what = MSG_Done;
  16.       m_Handler.sendMessage(msg);
  17.     }
  18.     catch (Exception e) {
  19.       e.printStackTrace();
  20.     }
  21.   } 
  22. };
  23.  
  24. private Handler m_Handler = new Handler(){
  25.   @Override
  26.   public void handleMessage(Message msg) {
  27.     super.handleMessage(msg);
  28.     switch (msg.what){
  29.       case MSG_INCREASE_PROGRESSBAR:
  30.         if (m_progressDialog != null)
  31.           m_progressDialog.incrementProgressBy(1);
  32.         break;
  33.       case MSG_DelteDone:
  34.         if (m_progressDialog != null){
  35.           m_progressDialog.dismiss(); 
  36.           m_progressDialog = null; 
  37.         }
  38.     } 
  39.   } 
  40. };

出現這個問題,海芋就去追查一下 Handler 這個 Class,原來在 Handler SendMessage 後,Handler 會將 Message 加入 MessageQueue 中,造成原本要處理的對象,已經不是原來的對象所致,所以要解決這個問題,必須在每次傳送 Message 給 Handler 前,先 New 一個 Message 元件,所以改成以下的寫法就可以囉!

  1. private int MSG_INCREASE_PROGRESSBAR = 9527;
  2. private int MSG_Done = 5566;
  3. private ProgressDialog m_progressDialog = null;
  4.  
  5. private Runnable m_runnable = new Runnable(){
  6.   @Override
  7.   public void run() {
  8.     try {
  9.       for (int i = 0; i < 100; i++){
  10.         Message msg = new Message();
  11.         msg.what = MSG_INCREASE_PROGRESSBAR;
  12.         m_Handler.sendMessage(msg);
  13.       }
  14.       Message msg = new Message();
  15.       msg.what = MSG_Done;
  16.       m_Handler.sendMessage(msg);
  17.     }
  18.     catch (Exception e) {
  19.       e.printStackTrace();
  20.     }
  21.   } 
  22. };
  23.  
  24. private Handler m_Handler = new Handler(){
  25.   @Override
  26.   public void handleMessage(Message msg) 
  27.   { 
  28.      super.handleMessage(msg);
  29.      switch (msg.what){
  30.        case MSG_INCREASE_PROGRESSBAR:
  31.          if (m_progressDialog != null)
  32.            m_progressDialog.incrementProgressBy(1);
  33.          break;
  34.        case MSG_DelteDone:
  35.          if (m_progressDialog != null){
  36.            m_progressDialog.dismiss(); 
  37.            m_progressDialog = null; 
  38.          }
  39.          break;
  40.      }
  41.   } 
  42. };