问题很简单。在 Android 上,我有一个需要调用库函数的方法。该呼叫将发出我必须处理的回调信号。在我从我的方法返回之前,我必须等待该回调发出信号。
我认为监视器对象上的 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);
}
回调如下,它与上面的方法在同一个类中,但它是 Android 中非常流行的“onSomeEvent()”之一:
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();
}
}
}
}