如何让应用程序只启动一个实例

 

缘起:最近做的RCP系统有如下需求,在系统中只允许一个应用程序窗口(实例)

 

使用过"金山词霸"或"有道词典"的朋友都知道。在"金山词霸"或"有道词典"已经运行了的情况下,两次点击上述程序的图标,那么它不会再运行另一个"金山词霸"或"有道词典",而是将已有的"金山词霸"或"有道词典"给激活,始终只能运行一个"金山词霸"或"有道词典"的实例。

 

在实际的程序开发中,通常会有这样的需求。

 

最近down了MyWork的源码下来研究,发现它是这么做的,主要是利用了ServerSocket的一个端口绑定的特性。代码很简单,如下:

//不允许启动第二个实例

final int port = ConfigHelper.getIntegerProperty("work.port");//①

if (port != 0) {

new Thread(){

public void run() {

try {

ServerSocket ss = new ServerSocket(port);

ss.accept();

}catch(BindException be){//②

//second instance not allowed

System.out.println("不允许启动第二个实例,请设置参数work.port");

System.exit(0);③

} catch (IOException e) {

e.printStackTrace();

}

}

}.start();

}

 

说明:

①这里为了不把port写死,通常会在配置文件中进行配置。硬编码灵活性也不好。因为很多时候这个端口可能被其他程序占用了。

②BindException试图将套接字绑定到本地地址和端口时发生错误的情况下,抛出此异常。这些错误通常发生在端口正在使用中或无法分配所请求的本地地址时。

③终止正在运行的Java虚拟机。参数用作状态码;根据惯例,非零的状态码表示异常终止。

④上面的代码在RCP中,当然是放在继承自AbstractUIPlugin类的插件类中的start方法当中了。记得要先调用

super.start(context);如下:

  /**

* This method is called upon plug-in activation

*/

public void start(BundleContext context) throws Exception {

super.start(context);

//删除安装遗留文件Hidecmd.exe

if(new File("Hidecmd.exe").exists())

new File("Hidecmd.exe").delete();

//不允许启动第二个实例

final int port = ConfigHelper.getIntegerProperty("work.port");

if (port != 0) {

new Thread(){

public void run() {

try {

ServerSocket ss = new ServerSocket(port);

ss.accept();

}catch(BindException be){

//second instance not allowed

System.out.println("不允许启动第二个实例,请设置参数work.port");

System.exit(0);

} catch (IOException e) {

e.printStackTrace();

}

}

}.start();

}

}

 

⑤个人觉得这个方法不一定是最好的。但是也是一个思路。

⑥.既然无意中看到了这个问题,就在网上搜索了一番。参考博客如下:

如何做到像《金山词霸》一样只运行一个实例(转_孙鑫老师原创)

http://hi.baidu.com/piaoliugogo/blog/item/424f03003c32e008728da519.html

让程序只运行一个实例的4种方法

http://blog.csdn.net/magictong/archive/2008/12/25/3603015.aspx

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值