Background Applications

The preceding pages cover much of what is needed to create a background application. Background applications could be considered to be either of these types:

  • minimized application--an application that has a card stage (or window) but is not in the foreground view

  • dashboard--an application that has a dashboard stage (or panel) but no card stage

Minimized Application

This is simply an application with a card stage that is not in the foreground view. There are some guidelines for minimized applications:

  • Generally an application should not post notifications or create a Dashboard stage unless the application is minimized or without any card stage at all. When the applications is maximized, all the user interface should be presented in the card view.

  • You can add a listener to the stageController's document element for Mojo.Event.stageDeactivate events which will indicate that the application is being minimized. A Mojo.Event.stageActivate event is sent when the application moves back into focus and is maximized. This will allow you to customize your application's behavior around these states. For example:

    MainAssistant.prototype.setup = function(){
      -
      -
      -
      this.activateHandler=this.activateWindow.bind(this);
      Mojo.Event.listen(this.controller.stageController.document,
          Mojo.Event.stageActivate, this.activateHandler);
      this.deactivateHandler=this.deactivateWindow.bind(this);
      Mojo.Event.listen(this.controller.stageController.document,
          Mojo.Event.stageDeactivate, this.deactivateHandler);
    };
    MainAssistant.prototype.activateWindow = function(event) {
      Mojo.Log.info(".................. Main Assistant - Maximized State");
    };
    MainAssistant.prototype.deactivateWindow = function(event) {
      Mojo.Log.info(".................. Main Assistant - Minimized State");
    };
    
    
  • When minimized, suspend application behavior that isn't necessary and lengthen polling cycles where possible. Since the application is minimized, it won't be immediately seen by the user, so work done to update the display isn't required. System calls, data connections, and similar requests should be limited where possible as they consume CPU and power, and lengthy operations will impact the responsiveness of the maximized application.

Dashboard Application

For some applications, the card stage can be closed and the application will continue to function using a Dashboard stage as the primary user interface. Email or messaging applications are classic examples of this, but some applications may find that the Dashboard is a better primary stage for their purpose. Consider a weather application, traffic monitor, friend finder or other location-based applications as possible Dashboard applications.

A typical Dashboard application will have three components:

  • the application assistant; opens the card stage at launch, and the dashboard stage when directed to.

  • the card stage and scene assistant; enables or disables the application and captures settings and preferences that drive the application behavior and feature set.

  • the dashboard stage and scene assistant; presents information gathered by the application, handles periodic wake-up events to update the information, and supports limited interaction.

Dashboard applications will have a parent window attached to the application controller and handles just the start-up events. The Dashboard will be updated as new status and information is available and notifications will be posted. If the Dashboard is closed for any reason, HP webOS will close the parent window and the application will be fully closed.

Most of this structure should be familiar; it combines techniques that have been covered in Advanced Application Guidelines and Dashboards and Notifications. The background processing is new. In this application model, setTimeout() is used to schedule periodic wakeup calls within the Dashboard scene. This extended sample shows how you might create a Dashboard that:

  • creates the initial Dashboard on launch...

  • sets up a wakeup cycle every 5 minutes and initiates the dashboard stage when the application is enabled through the card stage...

  • handles wakeups; in this demonstration, a new banner notification is posted, the dashboard is updated and a new wakeup timeout is scheduled...

  • closes the application when the user closes the dashboard.

function DashboardAssistant() {
  this.message = "Tracking Notifications";
  this.count = dashboardCount;
}

DashboardAssistant.prototype.setup = function() {
  // Display the dashboard
  this.updateDashboard(this.message, this.count);
  
  // Set up wakeup handler and first wakeup event
  this.wakeupFunction = this.wakeupHandler.bind(this);
  this.wakeupTaskId = this.controller.window.setTimeout(this.wakeupFunction, 300000);
};

DashboardAssistant.prototype.wakeupHandler = function() {
  var bannerMessage = "An update from MyApp";

  var bannerParams = {
      messageText: bannerMessage,
      soundClass: "alerts"
  };

  Mojo.Controller.getAppController().showBanner(bannerParams, {source: "notification"}, "MyApp");

  // Update dashboard
  dashboardCount = dashboardCount+1;
  this.updateDashboard(this.message, dashboardCount);
  this.wakeupTaskId = this.controller.window.setTimeout(this.wakeupFunction, 300000);
};

DashboardAssistant.prototype.updateDashboard = function(message, count) {
  var info = {message: message, count: count};

  // Use render to convert the object and its properties along with a view file into a string
  // containing HTML
  var renderedInfo = Mojo.View.render({object: info, template: 'dashboard/item-info'});
  var infoElement = this.controller.get('dashboardinfo');
  infoElement.innerHTML = renderedinfo;
};

// Close the dashboard
DashboardAssistant.prototype.cleanup = function() {
  this.controller.window.clearTimeout(this.wakeupTaskId);
  var appController = Mojo.Controller.getAppController();
  appController.closeStage(dashboardStage);
};

Of course, the use of setTimeout() will only wake up the application when the device is already awake or awakened for other reasons. If the device is asleep, then it won't be awakened, so you need to account for that in the timeout processing.

Alarms

To wake your application even while the device sleeps, use the Alarms service. It will not launch your application if it isn't running, but will wake the application in other cases. To modify the above sample to use Alarms, substitute a service call in place of setTimeout(). Pass the wakeup function (i.e., this.wakeupHandler.bind(this)) as the onSuccess callback in the service call.

Additional Guidelines

These are some additional guidelines for background applications:

  • Conserve power; poll as infrequently as possible. Space out your requests and implement degrading intervals that lengthen the longer your polling does not produce an event or data change.

  • Limit notifications; use the dashboard to update state and status and limit even banner notifications to important information.

  • Avoid background processing; while you're running, the user doesn't see any UI and your processing can have an adverse impact on the UI the user does see.