| ||||||||||||||||
| ||||||||||||||||
| ||||||||||||||||
|
Внезапное закрытие Java-приложения: как этого избежать?
Во многих случаях у программистов возникает необходимость выполнить некоторые действия в момент, когда пользователь заканчивает работу с приложением. Но проблема состоит в том, что пользователи не всегда пользуются рекомендованными и правильными способами выхода из приложения. Java предоставляет элегантный подход к выполнению какого-либо кода в середине процесса выгрузки процесса вашего приложения, таким образом гарантируя, что этот код, который, например, занимается какими-либо "очистительными" операциями, будет обязательно выполнен. Эта статья рассказывает о том, каким образом можно вешать обработчик прерывания работы приложения для гарантированного выполнения завершающего кода независимо от того, каким образом пользователь завершил работу с вашим приложением. package test;
public class ShutdownHook Demo {
public void start() {
System.out.println ("Demo");
ShutdownHook shutdown Hook = new ShutdownHook();
Runtime.getRuntime(). addShutdownHook(shutdownHook);
}
public static void main (String[] args) {
ShutdownHookDemo demo = new ShutdownHookDemo();
demo.start();
try {
System.in.read();
} catch (Exception e) {
;
}
}
}
class ShutdownHook extends Thread {
public void run() {
System.out.println ("Shutting down");
}
}
В качестве следующего примера мы рассмотрим простое Swing-приложение, главный класс которого называется MySwingApp. ![]() Листинг 2 package test;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
public class MySwingApp extends JFrame {
JButton exitButton = new JButton();
JTextArea jTextArea1 = new JTextArea();
String dir = System.getPro perty("user.dir");
String filename = "temp.txt";
public MySwingApp() {
exitButton.setText("Exit");
exitButton.setBounds(new Rectangle(304, 248, 76, 37));
exitButton.addActionListener(new java.awt.event.Action Listener() {
public void actionPerfor- med(ActionEvent e) {
exitButton_actionPerformed(e);
}
});
this.getContentPane().set Layout(null);
jTextArea1.setText("Click the Exit button to quit");
jTextArea1.setBounds(new Rectangle(9, 7, 371, 235));
this.getContentPane().add (exitButton, null);
this.getContentPane().add (jTextArea1, null);
this.setDefaultCloseOpera-tion(EXIT_ON_CLOSE);
this.setBounds(0,0, 400, 330);
this.setVisible(true);
initialize();
}
private void initialize() {
//создание временного файла
File file = new File(dir, filename);
try {
System.out.println("Crea-ting temporary file");
file.createNewFile();
} catch (IOException e) {
System.out.println("Failed creating temporary file.");
}
}
private void shutdown() {
//удаление временного файла
File file = new File(dir, filename);
if (file.exists()) {
System.out.println("Deleting temporary file.");
file.delete();
}
}
void exitButton_action Performed(ActionEvent e) {
shutdown();
System.exit(0);
}
public static void main (String[] args) {
MySwingApp mySwingApp = new MySwingApp();
}
}
При запуске это приложение вызывает метод initialize. Этот метод, в свою очередь, создает в текущей директории временный файл с именем temp.txt. private void initialize() {
//создание временного файла
File file = new File(dir, filename);
try {
System.out.println("Crea-ting temporary file");
file.createNewFile();
} catch (IOException e) {
System.out.println("Failed creating temporary file.");
}
}
Когда пользователь закрывает это приложение, то временный файл должен быть удален. В данном случае нам остается надеяться на то, что пользователь нажмет кнопку Exit, и по ее нажатию будет вызван метод shutdown, который и удаляет временный файл. Однако временный файл не будет удален в случае, если пользователь для выхода из программы воспользуется системной кнопкой X окна приложения или каким-либо другим способом. package test;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
public class MySwingAppWith ShutdownHook extends JFrame {
JButton exitButton = new JButton();
JTextArea jTextArea1 = new JTextArea();
String dir = System.getPro perty("user.dir");
String filename = "temp. txt";
public MySwingAppWithShut-downHook() {
exitButton.setText("Exit");
exitButton.setBounds(new Rectangle(304, 248, 76, 37));
exitButton.addActionListener(new java.awt.event.Ac-tionListener() {
public void actionPer-formed(ActionEvent e) {
exitButton_actionPerformed(e);
}
});
this.getContentPane().set Layout(null);
jTextArea1.setText("Click the Exit button to quit");
jTextArea1.setBounds(new Rectangle(9, 7, 371, 235));
this.getContentPane().add (exitButton, null);
this.getContentPane().add (jTextArea1, null);
this.setDefaultCloseOpera-tion(EXIT_ON_CLOSE);
this.setBounds(0,0, 400, 330);
this.setVisible(true);
initialize();
}
private void initialize() {
//добавление shutdown-ловушки
MyShutdownHook shutdown Hook = new MyShutdownHook();
Runtime.getRuntime().addShutdownHook(shutdownHook);
//создание временного файла
File file = new File(dir, filename);
try {
System.out.println("Crea-ting temporary file");
file.createNewFile();
} catch (IOException e) {
System.out.println("Failed creating temporary file.");
}
}
private void shutdown() {
//удаление временного файла
File file = new File(dir, filename);
if (file.exists()) {
System.out.println("Dele-ting temporary file.");
file.delete();
}
}
void exitButton_action Performed(ActionEvent e) {
shutdown();
System.exit(0);
}
public static void main (String[] args) {
MySwingAppWithShutdown Hook mySwingApp = new My SwingAppWithShutdownHook();
}
private class MyShutdown Hook extends Thread {
public void run() {
shutdown();
}
}
}
Обратите внимание на метод initialize. Первое, что он делает - создает экземпляр внутреннего класса MyShut-downHook, который наследует класс Thread. |
|
|
| ||||||||||||||||
|