Application Life Cycle

This overview describes the life cycle of a BlackBerry® device application. The life cycle of an application refers to the possible states and transitions that the application can move through from the time that it starts until it terminates.

BlackBerry devices support Java® ME compliant applications called MIDlets. The MIDlet life cycle is different than the BlackBerry device application lifecycle that is covered in this overview. There are many web sites available that cover the MIDlet life cycle.

The life cycle of a BlackBerry device application is simple. The application starts, runs, and terminates. During the running state, most applications receive and process events, and update their UI in response to those events.

The operating system on a BlackBerry device is multithreaded. It enables you to run multiple applications simultaneously. It supports broadcasting events to multiple applications and it supports running background threads.

BlackBerry device applications

BlackBerry device applications consist of one or more code modules. Code modules are stored in files with the .cod file name extension. Although an application can have a single code module, many applications have a group of code modules. Code modules and code module groups can include associated application metadata, such as vendor name and application version number.

To work with individual code modules, use the CodeModuleManager class. To work with code module groups, use CodeModuleGroup and CodeModuleGroupManager.

All applications include a class that is derived from either the Application class or the UiApplication class. To create an application with a UI, extend the UiApplication class. To create an application that does not require a UI, extend the Application class.

Starting

A BlackBerry device application can be started in the following ways:

Regardless of how an application starts, the Application Manager starts the process that the application runs in.

The ApplicationManager class enables applications to interact with the Application Manager to perform tasks, including the following:

Entry points

The Application Manager starts an application by creating a process and a thread within that process to invoke one of the entry points of the application. For modules that are configured as libraries, the entry point is libMain(). For all other modules, the entry point is main().

Although the execution of an application always starts with the same method, the benefits of multiple entry points are provided through the use of command-line arguments. You can specify multiple command-line arguments to pass to main() when it is invoked. Each call to main(), along with the command-line arguments that are specified, is referred to as an entry point.

You write code in main() that determines whether there are incoming arguments and performs appropriate tasks in response. So, although there is only one entry point method, you have a mechanism to perform different tasks in response to how an application is started.

The following code sample demonstrates how to determine if a command-line argument was passed to main().
public static void main(String[] args) 
{
     if ( args != null && args.length > 0 && args[0].equals("gui") )
     {
        //code corresponding to entry pt with cmdline arg "gui"
     } 
     else 
     {
        //code corresponding to standard entry pt
     }
}

Using more than one entry point lets you create different ways for users to start an application. For example, if your application allows users to create a new document, you might provide users with two icons that they can click to start the application. Users could click one icon to open the application to its home screen and the other icon to open the application to the screen that is required to create a new document.

You use application descriptors to specify command-line arguments to pass to main(). You create multiple entry points to an application by creating multiple application descriptors. For more information about how to create multiple entry points to an application, visit the Developer Knowledge Base to read the article How To - Setup an alternate entry point for my application

Application descriptors

Application descriptors contain information about an application. An application can have more than one application descriptor. For example, an application that has multiple entry points has an application descriptor corresponding to each of those entry points. To work with application descriptors, you can use the ApplicationDescriptor class.

The following code sample uses the ApplicationManager class to retrieve ApplicationDescriptors for each running UI application. The ApplicationDescriptors are used to retrieve information about each application.

Click for code sample: List properties of applications

import net.rim.device.api.system.ApplicationDescriptor;
import net.rim.device.api.system.ApplicationManager;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.container.MainScreen;


public class ListApplications extends UiApplication 
{
	StringBuffer strTmp = new StringBuffer();
	public static void main(String[] Args)
	{
		ListApplications app = new ListApplications();
		app.enterEventDispatcher();
	}
	public ListApplications()
	{
		ApplicationManager appMgr = ApplicationManager.getApplicationManager();
		ApplicationDescriptor[] ad = appMgr.getVisibleApplications();
		
		for(int i=0;i<ad.length;i++)
		{
			strTmp.append("Name: ");
			strTmp.append(ad[i].getName());
			strTmp.append('\n');
			strTmp.append("Module Name: ");
			strTmp.append(ad[i].getModuleName());
			strTmp.append('\n');
			strTmp.append("Version: ");
			strTmp.append(ad[i].getVersion());
			strTmp.append('\n');
			strTmp.append('\n');
		}
		this.pushScreen(new InfoScreen(strTmp.toString()));
	}
}

class InfoScreen extends MainScreen
{
	public InfoScreen(String strMsg)
	{
		RichTextField lf = new RichTextField(strMsg);
		add(lf);
	}
}

Running

After the Application Manager starts an application, the application can either run a series of commands until it completes, or it can enter a loop and process events until it receives an event that indicates that it should terminate.

A special thread called the event thread is associated with each application. The event thread has the event lock unless another thread has requests the lock by invoking Application.getEventLock(). Only the thread with the event lock can process incoming events and update the UI of its associated application.

Typically, an application invokes Application.enterEventDispatcher() near the beginning of main(). The thread that started the application by entering main(), acquires the event lock, and becomes the event thread.

public class MyApplication extends Application
{
    // Entry point for the app
    public static void main(String[] args)
    {
         MyApplication thisApp = new MyApplication();
         thisApp.enterEventDispatcher();
    }
 
    /** Create a new MyApplication instance. */
    public MyApplication()
    {
        // ... Application's start-up work done here when
        // ... entry point instantiates this class.
    }
}

After the call to enterEventDispatcher(), the application enters an event-processing loop. The event thread processes incoming messages and sends them to listeners that you create or listeners that are provided for you by the application framework.

Warning: Because the thread with the event lock is the only thread that can process events and update the UI of the application, you must be extremely careful not to use it to run instructions that could fail or take a long time to complete. For example, if you must open a network connection, you must create and use another thread.

To practice working with threads and updating the UI, see the Working with Multiple Processes and Threads section of the developer labs that are available on the BlackBerry® Developer Zone web site.

You may encounter situations where you want to update the UI from a non-event thread. You can perform this update in two ways. You can acquire and synchronize on the event lock, causing your thread to act like the event thread, or you can inject a event in the message queue of your application.

If you must perform a quick or urgent UI update, you should synchronize on the event lock. If it is acceptable to experience a delay before your task runs, you should inject an event in the message queue. In either case, you should not run tasks that might take a long time to complete or might block. If you use library calls in your task, make sure that you understand them well and only use them if they run quickly and do not block.

You inject an event as an object that implements Runnable. The event is handled by the event thread as it is received from the message queue. The event thread processes the event by invoking its run() method.

To inject runnable events in the message queue of your application, use one of the following methods: invokeAndWait() or invokeLater().

If you decide to synchronize on the event lock, you must quickly complete the UI update that you require and release the lock. Otherwise, your application will become unresponsive and might eventually be terminated by the operating system. You acquire the event lock by calling Application.getEventLock().

Terminating

You can invoke System.exit() to terminate an application. This method causes the BlackBerry® Java® Virtual Machine to terminate all of the processes of the caller and, as a result, all associated threads. Alternatively, you can terminate an application by popping the last screen off of the display stack, which results in a call to close(). The close() method invokes System.exit().

Note: It is good practice to manually deregister any listeners that you registered before terminating your application.

Because you will typically start the event dispatcher thread by invoking Application.enterEventDispatcher(), which loops indefinitely, your application should provide a way to terminate. Applications that interact with the user could provide a handler for a Close menu item, and applications that do not interact with the user could terminate when they receive an event that indicates that their task is complete.


Copyright 1999-2010 Research In Motion Limited. 295 Phillip Street, Waterloo, Ontario, Canada, N2L 3W8. All Rights Reserved.
Copyright 1993-2003 Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
Copyright 2002-2003 Nokia Corporation All Rights Reserved.
Java is a trademark or registered trademark of Sun Microsystems, Inc. in the US and other countries.