Can an AIR application restart itself?
Short answer: maybe.
Buzzword has an “Unrecoverable error” dialog that we put up if an internal error occurs and we don’t think it’s safe for the app to continue running. We give the user a chance to submit an error report to our servers, and then we let them click a button to restart. In the browser version, this reloads the browser page, which works fine.
In the AIR version, we’re doing it a different way. We make a call to launchApplication() in AIR.swf, followed immediately by a NativeApplication.nativeApplication.exit(). (For more information about how to use AIR.swf, see the AIR 1.1 online documentation.)
There are two serious problems with this approach. The first is that it introduces a race condition between the application exiting and the launchApplication() code looking to see if the app is already running. NativeApplication.exit() is much faster than launchApplication(), so it may be next to impossible to reproduce the race condition, but if your users can make it happen, they will. So occasionally a user will press “Restart,” and the app will quit but not restart.
The second problem is that AIR.swf can only be loaded while your app is online. So if the app crashes during a session in which it has never been online, this approach can’t work.
Neither of these problems is serious enough to avoid using the approach entirely, since the unrecoverable error dialog doesn’t show up that often anyway, and in the worst case scenario, the user will have to restart the application manually — not the end of the world.
(Sample code removed.)




David,
I’m curious how you globally trap “unrecoverable errors” and report meaningful information back to your servers for diagnosis. I’m developing a moderate size Flex/AIR app and the lack of a global error handling mechanism is quite frustrating. This is one of the most glaring oversights in Flex/AIR.
I’m curious how you handled this in Buzzword. I’ve tried numerous approaches to global error handling in Flex, but none are ideal. And even if one could catch all errors globally, stack trace information is not normally available making diagnosis much harder.
This could and should be much easier…
// get applicationID and publisher ID //
var descriptor:XML = nativeApplication.nativeApplication.applicationDescriptor;
var ns:Namespace = descriptor.namespaceDeclarations()[0]; var appID:String = descriptor.ns::applicationID;
var pubID:String = descriptor.ns::publisherID;
I second George’s comment. Well said. I’ve been wanting to do this for awhile since I had thought of a nice component this would make. Just like you see in Mac or Windows, you get an alert style prompt to send an error report to the server. But without globally error handling this is near impossible. If possible extremely painful.
Have you thought about dropping a sophomore file on the filesystem and then trying your launchApplication? In the section of your app where you check to see a version is already running, you could check to see if the sophomore file exists and ignore the checking code (making sure to delete the file on the filesystem at the same time).
In a .NET app I had to write a long time ago, we used the above approach. The file we ended up writing to disk was actually a struct of the information that we wanted to send to our server. We let the clean copy of our app send the data (we were under the assumption that one of the errors that could occur could prevent us from communicating properly to our syslog server).
Just a thought!
Apologies, the info I provided for getting the application and publishers ID is now old and out of date, for current versions of AIR it’s simpler :
var appID:String = nativeApplication.nativeApplication.applicationID;
var pubID:String = NativeApplication.nativeApplication.publisherID;