As you begin writing hybrid mobile apps using Icenium, one of the things you should know about early on are the "lifecycle events" that are a core part of PhoneGap/Apache Cordova. These events are emitted on the document and provide critical hooks (deviceready
, for example) for when your application behavior should execute. In this post we'll take a brief look at the most important/often-used lifecycle events.
This event is emitted when Cordova has fully loaded, and the device APIs it provides your app are ready to use. It's most likely going to be the spot that you start your application behavior. So how do we listen for it? You attach an event listener to the document like this:
document.addEventListener("deviceready", function() { // Your code here... });
The deviceready
event – unlike any other PhoneGap/Cordova lifecycle event – will immediately invoke any callbacks added to it after it has already emitted.
The online
event is emitted when the device goes online (kinda obvious, eh?), and the offline
event is the inverse of that. These events are helpful, but if they are your sole means of detecting whether or not your application is in an online or offline state, you're going to have a bad time. I wrote a series recently that covers connectivity management in a bit more depth – I recommend checking it out! As you'd expect, listening to the online
/offline
events looks just like deviceready
:
document.addEventListener("online", function() { // YES! We have a connection....or at least the device thinks we do }); document.addEventListener("offline", function() { // O NOES! No connection.... });
I highly recommend reading through the Connection API docs, since the online
/offline
events rely on the same information used by the Connection API. Not all devices report the connection type accurately. And remember, just because you have an internet connection doesn't mean the remote endpoints specific to your app are available AND just because your device's wifi or cellular data is turned on does not mean you can actually reach the internet.
As you'd expect, the pause
event is emitted when the user switches away from the app and it's put in the background:
document.addEventListener("pause", function() { navigator.notification.alert( "But Why do you want to leave me?!", noticeDismissed, "But Why?!", "Deal With It" ); });
Seriously - not that you'd want to annoy users with alerts when they move away from your app - but I shared the above snippet for a reason. The alert would be shown to the user right away on an Android device (despite the fact that the user is moving away from the app, you'd see the alert pop up as the app hides), but an iOS device wouldn't respond. Instead, an iOS device would process the alert when the app was brought back into the foreground. This is the case for any Cordova API calls (or any plugins that need to execute Objective-C code) inside pause
event handlers on iOS devices. The Cordova docs go into a bit more detail about an alternative event (resign
) which you can use on iOS devices.
The inverse of pause
, the resume
event is emitted when the app is brought back into the foreground.
document.addEventListener("resume", function() { navigator.notification.alert( "Aaaaaan we're back!!", noticeDismissed, "Missed You", "OK (but that's kinda creepy)" ); });
There's one catch, though. The above code could actually hang on iOS devices. Any code that requires user interaction (i.e. - alerts, etc.), should be wrapped in a setTimeout
call when executed from within a resume
event handler. So if we wanted to tell the user how much we missed them on iOS, our code would need to change to this:
document.addEventListener("resume", function() { setTimeout(function(){ navigator.notification.alert({ "Aaaaaan we're back!!", noticeDismissed, "Missed You", "OK (but that's kinda creepy)" }); }, 0); });
(For what it's worth, the resume handler appears to work fine without the need for a setTimeout
in iOS7, but the Cordova docs cover a wider use-case than just iOS7!)
If you have power concerns, or simply want to be aware of when the battery status changes (i.e. - charge drops, or the device is plugged in, etc.), you can use the batterystatus
event, which provides an event callback argument with level
(charge percentage) and an isPlugged
flag to indicate if the device is plugged in. (Unfortunately the level
property doesn't work on Windows Phone devices.)
document.addEventListener("batterystatus", function(info) { if(!info.isPlugged) { app.message("The battery level is currently " + info.level + "."); } });
You can also use the batterycritical
event – it's emitted when the battery reaches a critical threshold (which is device specific). It also provides the level
and isPlugged
data on the callback argument:
document.addEventListener("batterycritical", function(info) { if(!info.isPlugged) { app.message("The battery level is critically low (" + info.level + ")! Time to plug this puppy in!"); } });
There are several other events listed in the PhoneGap/Cordova documentation - things like menubutton
, backbutton
, searchbutton
and more. Not all of them apply to every platform (for example, backbutton
isn't emitted on an iOS device, but it would be emitted on an Android device). It's also important to get familiar with how events may differ between platforms (remember, for example, that Windows Phone doesn't include the battery level when battery status changes). As you utilize these events in your app, bear in mind that Cordova's documentation recommends that you attach your event listeners after the deviceready
event has been emitted, along these lines:
document.addEventListener("deviceready", function(info) { document.addEventListener("pause", handlePause); document.addEventListener("resume", handleResume); // etc. });