2013-06-06 67 views
0

我會搜索主題,HandlerHandlerThread了Java API,尺蠖,以及SO,並不能找到答案。當然,我也使用Eclipse的調試器來檢查我的'味精'。Android:如何在Message Queue中打開Runnable?

現狀:如果只允許一個工作線程來訪問它,你會怎麼那麼在一個Runnable與消息區分防止併發問題的數據模型,其handleMessage(Message msg)如果你入隊兩個消息和在同一個消息隊列中運行?

問:雖然我的Runnable執行通過handler.postDelayed(myRunnable)被張貼後,按計劃,我想檢查,而我的工作線程後,它切換了Runnable的內容,以便我可以適當地更新我的數據模型。

我歡迎所有的反饋,感謝您的時間!

下面是「MSG」的整個內容作爲由Eclipe的調試器顯示。這裏是否有足夠的信息來打開Runnable?

msg Message (id=830030887816) 
    arg1 0 
    arg2 0 
    callback null  
    data Bundle (id=830030968104) 
     mAllowFds true  
     mClassLoader BootClassLoader (id=830023329296) 
      packages HashMap (id=830023329320) 
      parent null  
     mFdsKnown true  
     mHasFds false 
     mMap HashMap (id=830030980304) 
     mParcelledData null  
    flags 1 
    next null  
    obj null  
    replyTo null  
    target IncomingHandler (id=830031033176) 
    what 0 
    when 180369888 

下面是我的工作線程的handleMessage()。具體來說,我實例化的HandlerThread作爲我的工作線程和束縛它的getLooper()到我的工作線程處理器。

@Override 
public void handleMessage(Message msg) { 

    // If this is a Runnable then I need to call my method. 
    // This next line is a hack to test for Runnable. 
    // I would like to know how to inspect this Runnable 
    if (0 == msg.arg2 && 0 == msg.arg1 && 0 == msg.what) 
     incrementStateMachineBecauseRunnableStarted(); 

    // Determine which action to take 
    // http://stackoverflow.com/questions/5021246/conveniently-map-between-enum-and-int-string 
     switch (Cmd.values()[msg.what]) { 

     case RECEIVE_NEW_LIST_EMPLOYEES: 
      receiveNewListEmployees(msg); 
      break; 

     case UPDATE_ONE_EMPLOYEE_STATE: 
      updateOneEmployeeState(msg); 
      break; 

     default: 
      Log.e(this.getClass().getName(), "unexpected message."; 
      break; 
} 

這是我排隊我的Runnable(我在我的工作線程運行這段代碼,所以它是將消息發送給自己,要在handleMessage(Message msg)後處理):

  // Create a new Runnable for this employee 
      PostUpdate update = new PostUpdate(employee); 
      // Post this Runnable with a sort delay 
      postDelayed(update, WAIT_BEFORE_PUSH_MS); 

.. 。這是我排隊我的信息(從另一個線程):

   Message msg = mHandler.obtainMessage(); 
       msg.what = Cmd.RECEIVE_NEW_LIST_EMPLOYEES.ordinal(); 
       msg.arg1 = 77; // deliberately inserting debug value 
       Bundle bundle = new Bundle(); 
       bundle.putParcelableArrayList(Cmd.RECEIVE_NEW_LIST_EMPLOYEES.toString(), mEmployees); 
       msg.setData(bundle); 
       mHandler.sendMessage(msg); 

最後,我的Runnable:

private class PostUpdate implements Runnable { 

    private final Employee mEmployee; 

    public PostUpdate(Employee employee) { 
     mEmployee = employee; 
    } 

    @Override 
    public void run() { 
     // Post update through network to MySql server 
     mDao.setState(mEmployee); 
    } 
} 
+0

我還要提到,我的非零值分配給我入隊,以確保我沒有曲解這個Runnable接口作爲一個「消息」 _every_消息ARG1。 –

回答

1

從使用調試器和檢查元素的結論是,您無法在handleMessage()中確定是否正在處理消息或可運行子句。

我在經驗上發現(通過消除),當我將所有消息設置爲msg.what時,我的所有Runnable都有msg.what == 0。小心使用!