2011-11-22 32 views
7

Tengo un programa en Java (con una guía de oscilación), y me gustaría que solo existiera 1 instancia. Si se intentó abrir otra instancia del programa, me gustaría que la instancia actual se ponga en primer plano.comprobar el programa java de instancia única

¿Cómo puedo hacer esto?

Gracias de antemano.

+6

http://stackoverflow.com/questions/2528844/only-one-swing-frame-window-opened-at-time – onurbaysan

+0

@mKorbel no es necesario publicar ningún código, la pregunta es clara y autónoma. La respuesta de Judas Imam es perfecta. – alf

+0

Formas alternativas de implementar una aplicación de instancia única: http://stackoverflow.com/questions/177189/how-to-implement-a-single-instance-java-application – ozhan

Respuesta

4

Inicie la aplicación utilizando Java Web Start e implemente SingleInstanceService del JNLP API. Aquí hay un demo. of the SingleInstanceService.

Si se intentó abrir otra instancia del programa, me gustaría que la instancia actual se ponga en primer plano.

Enganche eso en el método newActivation(String[]) del SingleInstanceListener. Se pasarán los argumentos que se proporcionaron para el nuevo lanzamiento. La instancia existente decide qué hacer con los nuevos argumentos (por ejemplo, cambiar archivo, agregar nueva pestaña, ignorar ...)

-3

Patrón Singletone:

class SingleInstance { 
private static SingleInstance instance; 

public SingleInstance getInstance() { 
    if (instance==null) 
     instance = new SingleInstance(); 
    return instance; 
} 

private SingleInstance() { 
//construct it! 
} 
} 
+2

Usar un singleton dentro de una aplicación no previene varias instancias de la aplicación (es decir, varias instancias de JVM). –

+0

Eso solo ayuda dentro de un cargador de clases; OP quiere algo más como "solo una instancia en la computadora" – alf

0

En C# que por lo general crear un objeto mutex en applicaiton comenzar. Si no puede crearlo/obtenerlo, ya se está ejecutando otra instancia de la aplicación. Lamentablemente, no estoy 100% seguro de si esto se comporta igual en Java o cuál es la sintaxis exacta.

Espero que esto ayude.

+5

(Un) Afortunadamente, los mutex de Java no se comparten entre los procesos. – alf

+1

@alf Gracias por la información, aprender algo nuevo todos los días ... Esto hace que mi respuesta sea inútil, pero tal vez exista otro desarrollador de C# que no lo sabía también. –

+0

No necesariamente inútil. La idea está ahí. Solo tienes que encontrar otra forma de implementar el mutex. –

2

No existe una instancia previa en Java, pero puede crear un archivo pid en el directorio temp (o/var/run). (Y hágala File.deleteOnExit() para limpiarlo de todos modos en la salida)

Para llevar la ventana existente a la parte superior, puede notificar el programa usted mismo, a través de named pipe, unix socket o java remote method call, etc. Un simple & sucio es escribir en un archivo pequeño, digamos $TEMP/foobar-app.bring-to-top, y el programa debe sondear periódicamente este pequeño archivo, si llega a existir, lleve la ventana a la parte superior y elimine este pequeño archivo.

Supongo que Java no podría manejar señales, es decir, kill -HUP PID puede no funcionar para aplicaciones Java. Incluso si pudiera, no todos los sistemas operativos tienen señales.

3

Puede hacerlo utilizando un ShutDownHook y un archivo de bloqueo, consulte este sencillo example.

Creo que es la forma más sencilla ...

+0

Estoy de acuerdo. Este es probablemente el enfoque más simple de implementar. Esto es lo que he estado usando. Hay un pequeño truco en el inicio para evitar el error de eliminación de archivos en Windows. –

1

Lo hice una vez con un zócalo y una ServerSocket:


En primer lugar, cuando se inicia la aplicación, hacen una ServerSocket escuchar en algún puerto, por ejemplo 4004. El truco es comprobar si arroja un IOException. Si lo hace, hay otra aplicación ejecutándose o el puerto es utilizado por otra aplicación (check this list for commonly used ports; Tenga en cuenta que los puertos TCP y UDP no se bloquean entre sí), de lo contrario, puede continuar con el inicio de la aplicación. Si una instancia se está ejecutando actualmente, es posible que desee notificarlo conectando un TCP Socket (que garantiza que su conexión llega, UDP no).

Aquí se muestra un ejemplo:

ServerSocket ss = null; 
try { 
    ss = new ServerSocket(4004); 
} catch (IOException ex0) { 
    // Port either occupied by your application or a foreign one 
    // -> Connect 
    Socket s = null; 
    try { 
     s = new Socket(); 
    } catch (Exception ex1) { 
     // Something went wrong 
    } 
    if (s != null) { 
     // Send some singnal 
    } 
} 
if (ss == null) { 
    // Close or do something else 
} 

(me escribió esto de mi memoria, por lo que algunas cosas que podría estar equivocado o podría hacerse mejor).

Cuestiones relacionadas