Хранить единичный экземпляр Java-приложения
У меня есть файл JAR, который отображает JFrame
когда это будет выполнено. Я не хочу разрешать дублирование выполнения моего файла Jar. Каждый раз перед созданием фрейма, используя Java, я хочу проверить, выполняется ли Jar. Если мое приложение. уже есть экземпляр на экране, я хочу вывести его на передний план.
Как я могу это сделать? Пожалуйста, предложите мне способ.
4 ответа
В Java нет обычного метода для отдельного экземпляра приложения. Однако вы можете использовать Socket
техника программирования для достижения вашей цели.
Когда экземпляр создается, он пытается прослушать ServerSocket
, Если бы это могло открыть ServerSocket
это означает, что нет другого экземпляра приложения. Таким образом, он держит ServerSocket
жить до тех пор, пока программа не будет закрыта. Если он не может открыть ServerSocket, это означает, что приложение уже имеет другой экземпляр. Таким образом, вы можете выйти из приложения молча. Кроме того, вам не нужно сбрасывать настройки при завершении работы приложения.
Попробуйте следующий пример
public class SingletonApplication extends JFrame implements Runnable {
//count of tried instances
private int triedInstances = 0;
//the port number using
private static final int PORT = 5555;
public static void main(String[] args) {
SingletonApplication application = new SingletonApplication();
application.setTitle("My Singleton Application");
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.setSize(500, 500);
application.setVisible(true);
}
public SingletonApplication() {
super();
//run socket listening inside a thread
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run() {
try {
//create server socket
ServerSocket serverSocket = new ServerSocket(PORT);
//listing the socket to check new instances
while (true) {
try {
//another instance accessed the socket
serverSocket.accept();
//bring this to front
toFront();
//change the title (addtional);
triedInstances++;
setTitle("Tried another instances : " + triedInstances);
} catch (IOException ex) {
//cannot accept socket
}
}
} catch (IOException ex) {
//fail if there is an instance already exists
try {
//connect to the main instance server socket
new Socket(InetAddress.getLocalHost(), PORT);
} catch (IOException ex1) {
//do nothing
} finally {
//exit the system leavng the first instance
System.exit(0);
}
}
}
}
РЕДАКТИРОВАТЬ:
Дополнительно: он может передавать ваши аргументы времени выполнения в основной экземпляр приложения через клиентSocket
, Таким образом, можно сделать основной экземпляр для выполнения требуемой задачи, такой как открытие файла или воспроизведение музыки, добавив некоторый дополнительный код для чтения InputStream
принятоSocket
при звонкеaccept()
метод.
У меня была такая же ситуация.
Что я сделал, я использовал, чтобы открыть file
в write
режим и delete
file
когда я закрываю приложение.
Делая это, у меня есть известное доказательство того, что моя программа работает.
Каждый раз, когда я открываю приложение, я проверяю наличие этого файла и, если я нахожу свой файл, он работает, то я использовал, чтобы предупредить его
"Экземпляр уже запущен".
Даже если кто-то пытается удалить этот файл, он говорит, что он открыт в другом приложении.
Я тоже использовал сокет, через RMI.
Приложение является хостом / сервером RMI, принимает удаленный вызов метода через порт.
В основном при запуске пытается в качестве клиента RMI получить сервер RMI на этот порт. Если вы делаете удаленный вызов, передавая аргументы командной строки (например, чтобы открыть другой документ). А потом выходит.
В качестве сервера, вызываемого этим удаленным методом, пользователь выводит приложение на передний план, используя toFront()
окна.
JUnique завершает первую часть - блокирует несколько экземпляров одной и той же программы. Получение существующего экземпляра, чтобы выйти на передний план - это еще одна задача, к которой я не знаю, как подойти.