Friday, April 29, 2011

PhoneGap Lifecycle Events

With the release of PhoneGap version 0.9.5 all of the major platforms (Android, BlackBerry and iOS) now support lifecycle events. Documentation for the events will be available in the Events section of docs.phonegap.com but I thought I'd put together a small post explaining it in more details.

Whenever talking about events a finite state diagram is usually the best place to start.


When you start an application the load event is fired when all of the content has finished loading.  You can register an event listener for the load event in the body tag.
<script type="text/javascript" charset="utf-8">

function onLoad() {
  // handle on load event
}
</script>

<body onload="onLoad()">

However, this is not the most important event from a PhoneGap perspective. The PhoneGap API is not ready until you receive the deviceready event.  You should register for the deviceready event in your load event handler.  Wait until you get this event before you start calling PhoneGap API commands.
<script type="text/javascript" charset="utf-8">

function onLoad() {
  document.addEventListener("deviceready", onDeviceReady, false);
}

function onDeviceReady() {
  // PhoneGap is ready to be used
}
</script>

<body onload="onLoad()">

Once your application is up and running you can register for a couple of other lifecycle events in pause and resume.  The pause event is called when your application leaves the foreground and is suspended by the operating system.  The application is not closed it is just in the Paused state.  When the application is returned from the background and placed into the foreground the resume event is fired and your app is back in the Running state.
<script type="text/javascript" charset="utf-8">

function onLoad() {
  document.addEventListener("deviceready", onDeviceReady, false);
}

function onDeviceReady() {
  // Register the event listener
  document.addEventListener("pause", onPause, false);
  document.addEventListener("resume", onResume, false);
}

function onPause() {
  console.log("I've been paused");
}

function onResume() {
  console.log("I've been resumed");
}

</script>

<body onload="onLoad()">

When you application exits the unload event is called.  This is a useful event if your application needs to save some state data. You would register your unload listener the same as you would for the load event by adding it to the body tag.
<body onload="onLoad()" onunload="onUnLoaded()">

It is worth noting that if your application is in the Running state when it told by the OS to unload it will first be paused so the pause event will fire before the unload event.

If you want the full HTML listing you can find it here.

22 comments:

Anonymous said...

Hi,

I tried to add pause and resume event on iPhone app. However if phone is locked at that time only this events fired not on app minimize and maximize.

Can you please let us know about this.

We are using same code in this post and phonegap js is latest 0.9.5.

Thanks,
Bipin

Simon MacDonald said...

Hi Sagar,

I'm not sure I understand you question. Are you saying the pause and resume events are not fired when the phone is locked? I'm at a loss as to how you would pause an app when the phone is locked.

Simon

Unknown said...

If i'm not mistaken, Sagar says that the pause and resume event doesn't fired when app was minimize and maximize. But, the event fired when the phone is locked.

Simon MacDonald said...

I've asked the iOS expert to look into what is going on and will report back when I know more.

Simon MacDonald said...

Our iOS person has found an issue with the events. Apparently the pause event isn't being fired until the app resumes. It looks like there is a bug. Does someone want to create an issue on GitHub for us?

Shazron said...

Not a bug, it turns out. See https://github.com/phonegap/phonegap-iphone/issues/84

Simon MacDonald said...

Sweet Shaz, thanks for the update.

Anonymous said...

Hi All,

I think issue is we were using alert to see if it comes when app minimize and maximize.

We will set some variable to see if it work for us or not?

ON BEHALF OF SAGAR

Bipin

Anonymous said...

Hi,

We have tried all possible solution to get it work. but neither of it work.

Basically what we want to achieve is as follows:

1). When app is minimize we want to fire one function that disconnect user's session from remote server using AJAX.

2). When app maximize we want to establish session again.

Now, following is happing while app minimize or maximize.

1). When app minimize onPause callback function is not calling up. no console log is there.

2). When app maximize onPause callback is called, followed by onResume callback.

Can you please guide us how i can achieve above thing.

Here is my code;
function onLoad()
{
document.addEventListener("deviceready",onDeviceReady,false);

}

function onDeviceReady()
{
document.addEventListener("pause", onPause, false);
document.addEventListener("resume", onResume, false);
}

function onPause() {
console.log("On PAUSE");
disconnect();
}

function onResume() {
connect();
}

Simon MacDonald said...

@Bipin

Read up on @Shazron's update to issue 84. I think the console.log doesn't fire correctly causing you to think that onPause hasn't been called when it really has been.

Anonymous said...

Hi Simon,

I have checked Shazron's update to issue 84.

As per me issue is we are sending 2-3 ajax request to disconnect user. Basically we are using strophe for openfire connection. What we want to do is logout user when app is minimized.

Now when app minimize our function is getting called. But as there are 2-3 request going back and forth, so when that request is happening app is minimized and subsequent request is not sent.

So, user is still online. I am not sure what is going on. But my primary conclusion is as above.

Please let us know if you can provide us more detail on this.

Thank you,
Bipin

Simon MacDonald said...

@Bipin

I think you are running into an issue because the request you make is async and it is not finishing before the app goes into the background.

John said...

When is the UnLoad event fired? I don't understand the difference between my app going into the background (on Pause) and actually being unloaded (terminated by the iOS).

Is there any way to programmatically file the unload event?

Simon MacDonald said...

@John, the unload event is fired when the document is unloaded from the web view. This can happen when the web view is terminated or if you move to another page in your app.

The pause event happens when your app goes into the background.

Unknown said...

very useful blog

Khalid Ali said...

Hi Simon, my question is a newbies question as I have just started to see how android and phonegap can be used. Here it is.
What I am trying to do is read file list from a folder on my phone (or sd card) I saw following code in one of the tutorials from this url
http://docs.phonegap.com/phonegap_file_file.md.html#LocalFileSystem
However, when use an alert to see if file system is loaded, I always get filesystem object as undefined. Is there a particular permission I need? Thanks in advance for your suggestions.

[code]
// Wait for PhoneGap to load
//
document.addEventListener("deviceready", onDeviceReady, false);

// PhoneGap is ready
//
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail);
window.resolveLocalFileSystemURI("file:///example.txt", onResolveSuccess, fail);
}

function onFileSystemSuccess(fileSystem) {
console.log(fileSystem.name);
}

function onResolveSuccess(fileEntry) {
console.log(fileEntry.name);
}

function fail(evt) {
console.log(evt.target.error.code);
}

[/code]

Simon MacDonald said...

Folks, for questions that aren't related to the post in question please pop on over the PhoneGap Google Groups and ask it. I'm just as likely to answer it over there.

@ Khalid Ali

I can't see why the code would cause you problem. Even the alert dialog wouldn't be a blocking call. It is generally better to use console.log() anyway.

Greg said...

Simon,

My question is around the Congfiguration changes in PhoneGap Android.

I am seeing that when the user closes "goes back to the home screen" and then back into the app, it forces the whole WebView to reload or the config to be reloaded.

How can I change this? Is there a config settings in the Maninfest?

Thanks,
Greg

Simon MacDonald said...

Greg, I'm going to answer your question over on the PhoneGap Google Group.

Greg said...

Ok great - thanks Simon! Sorry for bugging.

elsigh said...

Interestingly, unload is still not in the official lifecycle events doc...

an3ss said...

In my experience, the unload event does not fire when the app is unloded on Android. Maybe that's why it's not mentioned in the PhoneGap/Cordova docs?