这是我在Windows 7上找到的。即使先前的实例已存在,双击快捷方式时,Windows上的潮汐sdk应用程序也会创建新实例。您可以在Tide SDK Developer(1.4.2)上观察相同的事情,只需运行该应用程序,如果再次单击该快捷方式,它将启动一个新实例,而不是仅显示已存在的实例。有谁知道如何解决这一问题?还是有人修好了吗?
OSX版本不会显示此类问题
答案 0 :(得分:0)
所以我找到了一种在Windows中解决这个问题的方法。使用Ti.Process创建一个进程,让它运行以下命令
tasklist | find "YourAppName"
如果一个实例已经存在,则返回该字符串,否则返回一个空字符串。您可以在每次启动应用程序时检查此项以避免多个实例
答案 1 :(得分:0)
在后台运行tasklist
与平台有关,此外该解决方案仅阻止新实例启动 - 它不会聚焦已经运行的实例。还有另一种解决方案,它使用Ti.FileSystem.File.touch()
方法:此方法将尝试创建指定的文件,如果成功则返回true
,如果文件已存在则返回false
。最重要的是,它是原子的,这意味着它不应该为您的应用程序引入竞争条件。
要聚焦已经运行的实例,您需要让它知道它应该(显示和)聚焦自己。一旦应用知道它是唯一正在运行的实例,一种工作方法是运行HTTP服务器,并在收到请求时集中注意力。如果应用程序在启动时发现另一个实例已在运行,请改为创建HTTP客户端,连接到另一个实例的HTTP服务器并向其发送请求;请求完成后,退出。
示例实现(放在app.js文件的开头):
// enclose the logic in a closure, just to play it safe
(function(pidFile) {
// if creating the PID file fails, i.e. there is another instance
// of the app already running
if (!pidFile.touch()) {
// create a HTTP client
var client = Ti.Network.createHTTPClient({});
// add some event handlers
client.onload = function() {
Ti.App.exit();
};
client.onerror = function() {
Ti.App.exit();
};
// and dispatch
client.open('GET', 'http://localhost:9731/');
client.send();
} else {
// or, if creating the PID file succeeds,
// create a HTTP server and listen for incoming requests
var server = Ti.Network.createHTTPServer();
server.bind(9731, 'localhost', function(request, response) {
// this handler gets run when another instance of the app
// is launched; that's where you want to show the app window
// if it is hidden and focus it
if (!Ti.UI.getMainWindow().isVisible()) {
Ti.UI.getMainWindow().show();
}
Ti.UI.getMainWindow().focus();
// send some response back to the other instance
response.setContentType('text/plain');
response.setContentLength(2);
response.setStatusAndReason('200', 'OK');
response.write('OK');
});
// an important thing is to clean up on application exit
// - you want to remove the PID file once the application
// exits, or you wouldn't be able to run it again until you
// deleted the file manually, something you don't want the end user
// to deal with
Ti.API.addEventListener(Ti.EXIT, function() {
server.close();
pidFile.deleteFile();
});
}
// now call the closure passing in an instance of the Ti.Filesystem.File class
// wrapping the PID file in you app data directory
})(Ti.Filesystem.getFile(Ti.API.Application.getDataPath(), 'run.pid'));
可能有一种更轻量级的方式通过Ti.Network.TCPSocket
类连接两个实例(我现在正在研究这个问题)。要记住的另一件事是应用程序可能会崩溃,无法自行清理,因此,随后无法运行。因此,在HTTPClient的onerror
事件处理程序中,比退出更谨慎的方法是向用户显示“应用程序已经运行且没有响应,或者最近崩溃了”的对话框。你想强制启动应用吗?“此外,服务器的端口可能已经被另一个应用程序使用,或者可能是已经崩溃的先前运行的应用程序的僵尸 - 提供的代码不会考虑到这一点(只是说')。