這個問題很簡單。在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();
}
}
}
}
我想'connection.useNotify()/ setNotify()'使用布爾字段 - 該字段是如何聲明的?它是不穩定的嗎?另外:你應該總是在一個循環中調用'wait',除非你確定只有一個線程在等待,你應該使用'notifyAll'。 – assylias 2013-02-17 15:35:33
如果不是使用wait/notify使用高級併發API(例如CountdownLatch),而且您的生活會更簡單。 – assylias 2013-02-17 15:37:53
是的。這些只是幫助人員確定wait(10000)是否由於超時或由於notify()執行了任務而返回的。由於wait()什麼也沒有返回,所以沒有其他方法可以告訴。最後問題是調用方法每次嘗試都等待10秒鐘。 – 2013-02-17 15:38:45