我正在运行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(): 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 []数组只包含空引用。
答案 0 :(得分:2)
我可以确认我们已经在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();
}
但是,后面的事件循环会挂起(即display.readAndDispatch()/ display.sleep()dance)。我怀疑它不是因为不是主线程而读取UI事件。
我不确定是否有一种犹太方法来解决这个问题。在我的例子中,我们控制启动OSGi的主要JVM线程,因此我想在OSGi启动后添加一个可以运行SWT事件循环的钩子。
答案 1 :(得分:1)
我遇到的问题是,只要“display.sleep()”被调用,窗口就会冻结应用程序。如果其他人遇到同样的问题,那对我有用的解决方案就是添加: -XstartOnFirstThread 执行时到VM。
我试图让Areca Backup软件在我的Mac上运行,并且知道它正在工作:)
我的系统是:MacOsX Snow Leopard 10.6.2
再见 丹尼尔W。
答案 2 :(得分:1)
我遇到了同样的问题,并通过添加-d32
和-XstartOnFirstThread
答案 3 :(得分:0)
这段代码看起来很奇怪......这应该是一个Eclipse插件吗?你想做什么?我猜你正在尝试使用用户界面创建一个RCP插件。如果是这样,这就是答案:不要那样做。您的OSGi Activator不负责创建SWT显示事件循环。
在plugin.xml中创建一个应用程序扩展,以声明方式创建SWT引导程序。它看起来像这样:
<extension
id="application"
point="org.eclipse.core.runtime.applications">
<application>
<run
class="com.yourcompany.foo.Application">
</run>
</application>
</extension>
然后创建Application类(随意调用它),看起来像这样:
public class Application implements IApplication {
/* (non-Javadoc)
* @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
*/
public Object start(IApplicationContext context) {
Display display = PlatformUI.createDisplay();
try {
int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART) {
return IApplication.EXIT_RESTART;
}
return IApplication.EXIT_OK;
} finally {
display.dispose();
}
}
/* (non-Javadoc)
* @see org.eclipse.equinox.app.IApplication#stop()
*/
public void stop() {
final IWorkbench workbench = PlatformUI.getWorkbench();
if (workbench == null)
return;
final Display display = workbench.getDisplay();
display.syncExec(new Runnable() {
public void run() {
if (!display.isDisposed())
workbench.close();
}
});
}
}
显然要确保你的Manifest和运行时都有SWT插件(org.eclipse.ui)。
我希望有所帮助。