我使用Bluevoce最新版本(2.1.1快照)。
我有一个JavaFX
应用程序在Windows上运行蓝牙服务器(暂时)。
到目前为止,我可以管理:
StreamConnectionNotifier.acceptAndOpen()
; 对于响应式设计和增强性能,我的JavaFX对所有蓝牙相关事件(连接,等待客户端,断开连接,读取/写入数据)使用异步模式,以便UI保持尽可能顺利(对于Android也同样如此!),使用回调来相应地更新用户界面。
为了以最干净,最简单的方式处理线程,我创建了一个名为AsyncUtils
的非常简单的类。此类在内部管理线程池以在后台执行操作并公开一个公共方法:executeAsync()
。这是完整的代码:
/**
* Class helper offering solution to execute any give operations in an asynchronous way thanks
* to the usage of threads and threadpools. C# ThreadPool.QueueUserWorkItem() equivalent
*/
public final class AsyncUtils {
private final static ExecutorService executor =
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
/**
* Execute the given runnable in a threadpool internally managed by a <code>ExecutorService</code>
* @param runAsync the runnable to run in an asynchronous operation
* @throws IllegalArgumentException in case the runnable is null
* @see ExecutorService
* @see Executors
*/
public static void executeAsync(final Runnable runAsync) {
if (runAsync == null)
throw new IllegalArgumentException("runAsync MUST NOT be NULL");
executor.execute(runAsync);
}
}
因此,每次我需要在主UI线程之外处理操作时,我会将其委托给AsyncUtils.executeAsync()
。
我一直在许多其他应用程序(Android也是如此)中使用此模式而没有任何问题(或者至少我可能知道的任何问题......)。
但是对于 Bluecove ,我不明白,因为当关闭我的JavaFX应用程序窗口时,我的IDE( NetBeans )显示该应用程序仍在运行,阻止我重新启动它。
更糟糕的是,在我异步调用StreamConnectionNotifier.acceptAndOpen()
然后关闭应用程序的情况下,我的手机仍然可以连接到服务器!这清楚地表明调用仍在阻塞,并且运行它的线程仍然存在。但这是正常行为。
如果最终用户开始启动蓝牙服务器然后关闭应用,该应用应完全关闭并停止。所以我尝试了两种解决方案来实现,徒劳:
shutdownNow()
中添加了一个直接调用AsyncUtils
的{{1}}方法。但正如文件所说:尝试停止所有正在执行的任务,停止处理 等待任务,并返回正在等待的任务列表 执行。
尝试意味着它可能无效,这显然是我的情况。
在我的executor.shutdownNow()
课程中(我处理与蓝牙相关的所有内容)我创建了一个BluetoothManager
方法,执行stopServices()
。似乎没有任何该方法的文档,但使用调试器,我尝试了以下内容:
在我等待StreamConnectionNotifier.close()
返回的行处放置一个断点(意味着客户端连接或者我想要发生的事情,流程已停止且不再等待)
关闭应用程序并捕获该请求,以便告诉BluetoothManager停止所有操作:StreamConnectionNotifier.acceptAndOpen()
StreamConnectionNotifier.close()`
Stage.setOnCloseRequest() =>
确实会返回但我的应用程序仍在运行(并且我没有忘记释放调试器^^)。
我放置acceptAndOpen
的其他测试显示消息确实已打印,这意味着我已达到System.out.println("Thread execution completed in asyncStartBluetoothServer");
范围的末尾。此时,线程应该已经死了,因为无处可做。
我在调用AsyncUtils.executeAsync()
时也尝试不使用AsyncUtils.executeAsync()
,但它没有帮助:事实上它冻结了UI(正如预期的那样)并且应用程序仍在运行...
有没有人遇到Bluecove的线程问题?
也许我在看错了帖子。但是我使用StreamConnectionNotifier.acceptAndOpen()
的唯一其他情况是发送消息(我不是)并监听传入消息(使用阻塞AsyncUtils.executeAsync()
)但这没有任何意义,因为我只是开始在InputStream.read()
之后和相同的线程(相同的范围)中阅读!由于我要求关闭StreamConnectionNotifier.acceptAndOpen()
,我不应该使用StreamConnectionNotifier
的流,因为没有连接的客户端...
答案 0 :(得分:0)
好吧,经过多次测试后,它似乎是StreamConnectionNotifier.close()
和AsyncUtils.shutdownNow()
的组合。
但在某些情况下,ExecutorService
似乎没有在其中一个线程内部抛出异常时关闭(因为调用StreamConnectionNotifier.close()
确实在我的代码和内部引发了一些异常。
但我设法让我的应用程序完全停止。
我有关于此问题的其他详细信息,我将在此处发布。