我正在运行 Mac OS X Snow Leopard,并且不想从 OSGi 包中的激活器访问显示。
下面是我的激活器的启动方法:
@Override
public void start(BundleContext context) throws Exception {
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new Runnable() {
@Override
public void run() {
Display display = Display.getDefault();
Shell shell = new Shell(display);
Text helloText = new Text(shell, SWT.CENTER);
helloText.setText("Hello SWT!");
helloText.pack();
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
});
}
在 Windows 环境中调用此代码工作正常,但在 Mac OS X 上部署我得到以下输出:
2009-10-14 17:17:54.050 java[2010:10003] *** __NSAutoreleaseNoPool(): NSCFString 类的对象 0x101620d20 自动释放,没有适当的池 - 只是泄漏
2009-10-14 17:17:54.081 java[2010:10003] *** __NSAutoreleaseNoPool(): NSCFNumber 类的对象 0x100119240 自动释放,没有适当的池 - 只是泄漏
2009-10-14 17:17:54.084 java[2010:10003] *** __NSAutoreleaseNoPool(): NSCFString 类的对象 0x1001024b0 自动释放,没有适当的池 - 只是泄漏
2009-10-14 17:17:54.086 java[2010:10003] *** __NSAutoreleaseNoPool(): NSCFString 类的对象 0x7fff701d7f70 自动释放,没有适当的池 - 只是泄漏
2009-10-14 17:17:54.087 java[2010:10003] *** __NSAutoreleaseNoPool(): NSCFString 类的对象 0x100113330 自动释放,没有适当的池 - 只是泄漏
2009-10-14 17:17:54.092 java[2010:10003] *** __NSAutoreleaseNoPool(): NSCFData 类的对象 0x101624540 自动释放,没有适当的池 - 只是泄漏
.
.
.
我使用 -XstartOnFirstThread VM 参数没有任何运气。我在使用 64 位 Cocoa,但我也尝试过 32 位 Cocoa。
尝试使用 Carbon 时出现以下错误:
位置 00000020 eip=9012337c 的内存访问无效
在调试 Display 类时,我可以看到 Displays[] 数组仅包含空引用。
最佳答案
我可以确认我们成功运行了 SWT 碳 在 Mac OS X 上,它自己的事件循环由捆绑激活启动,所以这绝对是可能的!这是在启动 VM 时使用 -XstartOnFirstThread。
但是 ,使用 Cocoa SWT(64 位),我看到同样的错误 :(
看起来,虽然我们运行 Carbon SWT 的方式有效,但它可能并不可靠:我们通过另一个线程驱动事件循环,而不是您应该做的主线程。在 Cocoa SWT 下,这不再起作用,而且这可能是一种狡猾的做法。
在创建 Display(改编自 Cocoa SWT Device 构造函数)之前,我可以使用以下 hack 修复线程池错误:
NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
NSThread nsthread = NSThread.currentThread();
NSMutableDictionary dictionary = nsthread.threadDictionary();
NSString key = NSString.stringWith("SWT_NSAutoreleasePool");
id obj = dictionary.objectForKey(key);
if (obj == null) {
NSNumber nsnumber = NSNumber.numberWithInteger(pool.id);
dictionary.setObject(nsnumber, key);
} else {
pool.release();
}
但是,随后的事件循环挂起(即 display.readAndDispatch ()/display.sleep () 跳舞)。我怀疑它只是没有读取 UI 事件,因为它不是主线程。
我不确定是否有犹太洁食方法来解决这个问题。在我的例子中,我们控制启动 OSGi 的主 JVM 线程,所以我想在其中添加一个可以在 OSGi 启动后运行 SWT 事件循环的钩子(Hook)。
关于swt - 在 Mac OS X 上无法获得 SWT 显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1567144/