我的java应用程序的主类有一个静态初始化器,在调用main()之前,我们在其中设置ApplicationAdapter以侦听来自操作系统的通知。到目前为止,这已经如预期的那样奏效了。然而,最近(从10.7开始?不确定时间表),有时这不起作用。调试应用程序后,操作系统似乎在事件线程上异步发布文件打开事件,而静态初始化器仍在运行。因此,有时初始化在文件打开事件发布之前完成(并且文件被正确打开),而其他时候,事件在初始化完成之前发布(即,在我的应用程序有机会注册ApplicationListener之前),因此我的应用程序永远没有机会处理事件,请求的文档也不会打开。
其他人遇到过这个问题吗?
我尝试过的一种可能的解决方案是暂停事件队列,就像在主类的静态初始值设定项的开头一样,类似于:
static{
final Object monitor = new Object();
SwingUtilities.invokeLater( new Runnable(){
public void run(){
synchronized( monitor) {
try{ monitor.wait(); } catch( Exception e ){ e.printStackTrace(); }
}
}
});
registerApplicationListener();
synchronized( monitor) {
try{ monitor.notifyAll(); }
catch(Exception e){ e.printStackTrace(); }
}
}
当应用程序初始化设置ApplicationListener以接收OS事件时,这会阻止事件调度。然而,问题仍然存在,操作系统仍然可以在初始化完成之前调度事件,据我所知,对此我无能为力。Apple Java扩展API中没有任何内容表明可以控制事件调度行为。我也没有找到任何方法来通过Info.plist.中的配置来控制事件调度的任何方面
确认这是来自OS X shell的文件打开事件。Java应用程序无法可靠地捕获此通知,解决方法是安装一个启动守护程序来捕获通知并将其作为启动参数转发给应用程序。
为应用程序注册URL方案也可能有效,但我从未在Java应用程序中尝试过,希望params会出现在main()args 中