我有一个rcp应用程序,它只运行第一次运行,当用户尝试重新执行应用程序时,第二个实例表现为客户端,它通过套接字编码并将其参数发送到充当服务器的第一个实例然后默默地退出。第一个实例接收并解码该消息,然后表现得好像是用这些参数调用的。
到目前为止,我做了很好的内部协议规范,用于在两个实例之间传递参数。
我无法将第一个实例(RCP应用程序)带到前面。它只处于最小化状态,
这是我之前的question
的延续我对上一篇文章所做的更改是应用程序类的启动方法
public Object start(IApplicationContext context) throws Exception {
if (!ApplicationInstanceManager.registerInstance()) {
return IApplication.EXIT_OK;
}
ApplicationInstanceManager
.setApplicationInstanceListener(new ApplicationInstanceListener() {
public void newInstanceCreated() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
System.out.println("New instance detected...");
//Display.getCurrent().getActiveShell()
.forceActive();// this gives null
// pointer exception
// hence commented
}
});
}
});
Display display = PlatformUI.createDisplay();
try {
int returnCode = PlatformUI.createAndRunWorkbench(display,
new ApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART)
return IApplication.EXIT_RESTART;
else
return IApplication.EXIT_OK;
} finally {
display.dispose();
}
}
以下线阻止我将应用程序带到前面
Display.getCurrent().getActiveShell().forceActive();
在getActiveShell()
生成空指针异常如何最大化前一个实例或将其带到前面
答案 0 :(得分:2)
我编写了一个实例管理器来将我的RCP限制为单个实例。
以下是Application.java
方法start
中的代码:
if (!ApplicationInstanceManager.registerInstance()) {
return IApplication.EXIT_OK;
}
ApplicationInstanceManager
.setApplicationInstanceListener(new ApplicationInstanceListener() {
public void newInstanceCreated() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (DEBUG)
System.out.println("New instance detected...");
Display.getCurrent().getActiveShell().forceActive();
}
});
}
});
这是监听器界面:
public interface ApplicationInstanceListener {
public void newInstanceCreated();
}
这是经理类:
public class ApplicationInstanceManager {
private static final boolean DEBUG = true;
private static ApplicationInstanceListener subListener;
/** Randomly chosen, but static, high socket number */
public static final int SINGLE_INSTANCE_NETWORK_SOCKET = 44331;
/** Must end with newline */
public static final String SINGLE_INSTANCE_SHARED_KEY = "$$RabidNewInstance$$\n";
/**
* Registers this instance of the application.
*
* @return true if first instance, false if not.
*/
public static boolean registerInstance() {
// returnValueOnError should be true if lenient (allows app to run on
// network error) or false if strict.
boolean returnValueOnError = true;
// try to open network socket
// if success, listen to socket for new instance message, return true
// if unable to open, connect to existing and send new instance message,
// return false
try {
final ServerSocket socket = new ServerSocket(
SINGLE_INSTANCE_NETWORK_SOCKET, 10, InetAddress
.getLocalHost());
if (DEBUG)
System.out
.println("Listening for application instances on socket "
+ SINGLE_INSTANCE_NETWORK_SOCKET);
Thread instanceListenerThread = new InstanceListenerThread(socket);
instanceListenerThread.start();
// listen
} catch (UnknownHostException e) {
EclipseLogging.logError(RabidPlugin.getDefault(),
RabidPlugin.PLUGIN_ID, e);
return returnValueOnError;
} catch (IOException e) {
return portTaken(returnValueOnError, e);
}
return true;
}
private static boolean portTaken(boolean returnValueOnError, IOException e) {
if (DEBUG)
System.out.println("Port is already taken. "
+ "Notifying first instance.");
try {
Socket clientSocket = new Socket(InetAddress.getLocalHost(),
SINGLE_INSTANCE_NETWORK_SOCKET);
OutputStream out = clientSocket.getOutputStream();
out.write(SINGLE_INSTANCE_SHARED_KEY.getBytes());
out.close();
clientSocket.close();
System.out.println("Successfully notified first instance.");
return false;
} catch (UnknownHostException e1) {
EclipseLogging.logError(RabidPlugin.getDefault(),
RabidPlugin.PLUGIN_ID, e);
return returnValueOnError;
} catch (IOException e1) {
EclipseLogging
.logError(
RabidPlugin.getDefault(),
RabidPlugin.PLUGIN_ID,
"Error connecting to local port for single instance notification",
e);
return returnValueOnError;
}
}
public static void setApplicationInstanceListener(
ApplicationInstanceListener listener) {
subListener = listener;
}
private static void fireNewInstance() {
if (subListener != null) {
subListener.newInstanceCreated();
}
}
public static void main(String[] args) {
if (!ApplicationInstanceManager.registerInstance()) {
// instance already running.
System.out.println("Another instance of this application "
+ "is already running. Exiting.");
System.exit(0);
}
ApplicationInstanceManager
.setApplicationInstanceListener(new ApplicationInstanceListener() {
public void newInstanceCreated() {
System.out.println("New instance detected...");
// this is where your handler code goes...
}
});
}
public static class InstanceListenerThread extends Thread {
private ServerSocket socket;
public InstanceListenerThread(ServerSocket socket) {
this.socket = socket;
}
@Override
public void run() {
boolean socketClosed = false;
while (!socketClosed) {
if (socket.isClosed()) {
socketClosed = true;
} else {
try {
Socket client = socket.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
String message = in.readLine();
if (SINGLE_INSTANCE_SHARED_KEY.trim().equals(
message.trim())) {
if (DEBUG)
System.out.println("Shared key matched - "
+ "new application instance found");
fireNewInstance();
}
in.close();
client.close();
} catch (IOException e) {
socketClosed = true;
}
}
}
}
}
}
答案 1 :(得分:2)
启动IApplication后,您还可以使用org.eclipse.osgi.service.datalocation.Location.isSet()
和org.eclipse.osgi.service.datalocation.Location.lock()
通常使用以下代码从您的Activator中检索位置:
public Location getInstanceLocation() {
if (locationTracker == null) {
Filter filter = null;
try {
filter = context.createFilter(Location.INSTANCE_FILTER);
} catch (InvalidSyntaxException e) {
// ignore this. It should never happen as we have tested the
// above format.
}
locationTracker = new ServiceTracker(context, filter, null);
locationTracker.open();
}
return (Location) locationTracker.getService();
}