Mat*_*ist 6 swt osgi eclipse-rcp
我正在运行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();
}
});
}
Run Code Online (Sandbox Code Playgroud)
在Windows环境中调用此代码可以正常工作,但在Mac OS XI上部署会得到以下输出:
2009-10-14 17:17:54.050 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x101620d20 of class NSCFString autoreleased with no pool in place - just leaking 2009-10-14 17:17:54.081 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x100119240 of class NSCFNumber autoreleased with no pool in place - just leaking 2009-10-14 17:17:54.084 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x1001024b0 of class NSCFString autoreleased with no pool in place - just leaking 2009-10-14 17:17:54.086 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x7fff701d7f70 of class NSCFString autoreleased with no pool in place - just leaking 2009-10-14 17:17:54.087 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x100113330 of class NSCFString autoreleased with no pool in place - just leaking 2009-10-14 17:17:54.092 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x101624540 of class NSCFData autoreleased with no pool in place - just leaking . . .
我没有运气就使用了-XstartOnFirstThread VM参数.我在64位Cocoa上,但我也试过32位Cocoa.
尝试使用Carbon时出现以下错误:
Invalid memory access of location 00000020 eip=9012337c
调试Display类时,我可以看到Displays []数组只包含空引用.
我可以确认,我们在 Mac OS X 上成功地在其自己的事件循环中运行了 SWT Carbon,该事件循环由捆绑激活启动,因此这绝对是可能的!这是在启动 VM 时使用 -XstartOnFirstThread。
但是,使用 Cocoa SWT(64 位),我看到同样的错误:(
看来,虽然我们运行 Carbon SWT 的方式有效,但它可能并不合规:我们是通过另一个线程驱动事件循环,而不是您应该的主线程。在 Cocoa SWT 下,这不再起作用,而且无论如何这可能是一种狡猾的做法。
在创建 Display 之前,我可以使用以下 hack 修复线程池错误(改编自 Cocoa SWT Device 构造函数):
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();
}
Run Code Online (Sandbox Code Playgroud)
然而,随后的事件循环挂起(即display.readAndDispatch()/display.sleep()之舞)。我怀疑它只是因为不是主线程而没有读取 UI 事件。
我不确定是否有一个彻底的方法来解决这个问题。就我而言,我们控制启动 OSGi 的主 JVM 线程,因此我正在考虑在其中添加一个钩子,以便在 OSGi 启动后运行 SWT 事件循环。