2013-02-17 52 views
1

這個問題很簡單。在Android上,我有一個需要調用庫函數的方法。該電話會發出我必須處理的回調信號。在我從我的方法返回之前,我必須等待該回調信號。wait()沒有通過notify()回調

我認爲監視器對象上的wait()和notify()方法會起作用。它不是。

基本上監控對象被稱爲Connection,我在調用方法中實例化。然後,該方法執行一個循環,在該循環中調用Android庫方法來「註銷」一個對象。不幸的是,這種方法的迴應在一些回調中給出。所以我使用Connection.wait(10000)方法來等待回調,並且在回調函數中我使用connection.notify()來表示何時完成(當然全部同步)。但是,connection.notify()不釋放connection.wait(10000)。我可以從Android logcat看到註銷成功,但是我總是需要等待10秒才能嘗試下一個註銷任務。

調用方法和回調的代碼如下。我在推理中做出了什麼愚蠢的假設,即失敗了。據我可以看到調用方法(線程)肯定擁有監控對象,並將其提供給connection.wait(10000)上的回調!

也許我對這個問題採用完全不正確的方法? (我想是阻塞調用者,直到所有的註銷,完成的方法。)

public void clearRegistrations() 
{ 
    connection = new Connection(); 
    // Tell the callback to notify() when a result is obtained 
    connection.setUseNotify(true); 
    for(BluetoothHealthAppConfiguration btConfig : btHealthAppConfigs) 
    { 
     // Initialize Connection object to not connected 
     connection.setConnectionState(false); 
     if(btHealth.unregisterAppConfiguration(btConfig)) 
     { 
      try 
      { 
       synchronized (connection) 
       { 
        connection.wait(10000); 
        // See if we were signaled or timed out 
        if(!connection.getConnectionState()) 
        { 
         Log.i(TAG, "Unregistration attempt timed out or failed; trying next un-registration"); 
        } 
       } 
      } 
      // This should not happen 
      catch(InterruptedException ie) 
      { 
       Log.i(TAG, "The InterrupedException is signaled."); 
      } 
      // This should not happen. 
      catch(IllegalMonitorStateException ime) 
      { 
       Log.i(TAG, "wait() method threw an IllegalMonitorStateException. Message: " + ime.getMessage()); 
      } 
     } 
     else 
     { 
      Toast.makeText(context, "Un-Registration API returned failure", Toast.LENGTH_SHORT).show(); 
     } 
    } 
    btHealthAppConfigs.clear(); 
    connection.setConnectionState(false); 
    connection.setUseNotify(false); 
} 

回調如下所示,它是在同一個班以上的方法,但它是其中的一個「onSomeEvent ()'在Android中非常流行:

public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration btAppConfig, int status) 
    { 
     if (status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_FAILURE) 
     { 
      Log.i(TAG, "Un-Registration of the Bluetooth Health Application failed"); 
      if(connection.useNotify() == true) 
      { 
       synchronized (connection) 
       { 
        Log.i(TAG, "Signal unregistration failure"); 
        // just indicate signaled 
        connection.setConnectionState(true); 
        connection.notify(); 
       } 
      } 
     } 
     else if(status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS) 
     { 
      Log.i(TAG, "Un-Registration of the Bluetooth Health Application successful"); 
      if(connection.useNotify() == true) 
      { 
       synchronized (connection) 
       { 
        Log.i(TAG, "Signal unregistration success"); 
        connection.setConnectionState(true); 
        connection.notify(); 
       } 
      } 
     } 
    } 
+0

我想'connection.useNotify()/ setNotify()'使用布爾字段 - 該字段是如何聲明的?它是不穩定的嗎?另外:你應該總是在一個循環中調用'wait',除非你確定只有一個線程在等待,你應該使用'notifyAll'。 – assylias 2013-02-17 15:35:33

+0

如果不是使用wait/notify使用高級併發API(例如CountdownLatch),而且您的生活會更簡單。 – assylias 2013-02-17 15:37:53

+0

是的。這些只是幫助人員確定wait(10000)是否由於超時或由於notify()執行了任務而返回的。由於wait()什麼也沒有返回,所以沒有其他方法可以告訴。最後問題是調用方法每次嘗試都等待10秒鐘。 – 2013-02-17 15:38:45

回答

0

有一堆東西可能是錯誤的代碼:assylias得到了他們中的大多數。顯而易見的是你肯定需要使用notifyAll,而不是通知。通知重新啓動某個等待鎖的線程; notifyAll重新啓動它們。

useNotify和setConnectionState也需要同步。此外,您還需要確保您鎖定的連接實例在兩個部分中都是相同的,並且與您呼叫通知的實例相同。最後,你需要保證呼叫通知實際上發生在等待呼叫之後。

就方法而言,無論何時您使用這樣的低級工具,您都應該懷疑是否沒有更好的方法。有幾個更高層次的構造可以更簡單地做到這一點。我建議你嘗試重新設計你的代碼,這樣你就不會在回調中等待。撥打電話,將狀態停放在某處,然後在發生時處理回撥。

+0

我無法消除回撥在這種情況下。它是圖書館的一部分,我必須等到它完成(最好不睡覺)。我已經成功地使用了wait/notify,正如你在這段代碼中看到的,除了wait()成功的情況下,它是由被調用的方法創建的線程啓動的。當然,這並沒有阻止創建線程的方法。從logcat消息中可以清楚地看到,除了wait()的發佈之外,所有事情都按預期發生。我確信你是正確的,因爲COnnection對象由於某種原因不屬於調用者。 – 2013-02-17 19:02:24

+0

@Brian:不建議你消除回調!只是不要等待「等待」。相反,把你的狀態放在某個地方,做其他的事情,當回調發生時,把它拿起來。我建議記錄你等待的對象的id,同步和通知。我敢打賭,他們不是同一個對象。祝你好運! – 2013-02-17 19:36:10

+0

謝謝布萊克。使用CountDownLatch是SOOO容易,我正在放棄等待/通知。如果時間允許,我仍然想最終找出我做錯了什麼。 – 2013-02-17 20:20:55

相關問題