我正在制定个人规划程序。我利用XML文档来存储用户数据和登录数据。这不使用服务器,并且在程序中创建的所有帐户都本地化到存储它的计算机(在XML文档中)。
在登录 XML 文档中,我跟踪已登录的用户,以便一个用户不能同时拥有两个窗口,以防止与数据发生任何冲突。此功能运行流畅,我没有问题。
我唯一想知道的是是否有某种方法可以捕获程序的意外关闭(例如任务管理器关闭或在关闭计算机时强制关闭),以便我可以"登录"用户从XML文档中。否则,用户在意外程序关闭后将永远无法重新打开,而无需进入 XML 文档并从登录列表中删除用户名。
似乎关闭钩子不能很好地与 java GUI 的事件队列一起使用。 很像这个线程我尝试完全按照所示设置我的代码,但关闭钩子也对我不起作用。对于在没有关机挂钩的情况下捕获意外关机的方法,是否有任何建议?
这是我的代码:
import java.awt.EventQueue;
public class Gui {
private static Controller controller;
public static void main (String[] args) {
controller = new Controller();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
controller.saveState();
controller.logUserOut();
}
});
EventQueue.invokeLater(
new Runnable() {
public void run() {
controller.start();
}
});
}
}
这是对我的控制器的仔细观察,该控制器将用户注销
public void logUserOut() {
loginDatabase.logUserOut(username);
saveLoginState();
}
loginDatabase 所做的只是从登录用户列表中删除该用户名,以便用户可以自由地再次登录
public void saveLoginState() {
XStream xStream = new XStream(new DomDriver());
OutputStream outFile;
try {
String filePath = "data" + File.separator + "loginDatabase.xml";
outFile = new BufferedOutputStream(new FileOutputStream(filePath));
xStream.toXML(loginDatabase, outFile); // This writes your state to the outputFile;
outFile.close(); //close the writer
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
这是我在登录状态 xml 文件上写入的过程。我怀疑对于关闭钩子来说可能太长了,即使它实际上按我的预期被调用。
有什么建议吗?我想了很长时间可能使用简单的变量来解决问题,但由于我设置了程序,以便用户可以登录到多个帐户,因此无法使用变量。
此外,关闭挂钩作用域中包含的控制器对象是否与事件队列作用域中修改的控制器相同?
关闭钩子可以在这里成为解决方案。有关详细信息,请参阅例如此答案:https://stackoverflow.com/a/2541618/2045440
[题外话] 但是,如果您面临应用程序意外终止可能导致重要数据丢失的风险,也许值得考虑处理此数据的更持久的方式(自动保存、备份文件等)。
我通过检查操作系统的任务管理器解决了这个问题。它允许我查看xml文档所说的登录用户是否实际上打开了一个程序。如果没有,那么我知道有问题。这是对我的特定程序的修复程序,但它也可能对其他人有所帮助。
该线程的链接在这里。