Application lifecycle APIs
The lifecycle of an application refers to the possible states and transitions that an app can move through from the time it starts until it terminates. The lifecycle of a BlackBerry app is straightforward: it starts, runs, and terminates. During the running state, most apps receive and process events and update their UI accordingly.
All apps have an application class derived from either Application or UiApplication. If you want to create an app with a UI, then your app should extend UiApplication. Otherwise, your app should extend Application.
A BlackBerry app can be started in a number of ways:
- A user clicks an icon on the home screen.
- The system automatically starts the app when the smartphone starts.
- Another app starts the app.
- The system starts the app at a scheduled time.
Regardless of how an app is started, the Application Manager is responsible for starting the process that the app runs within. The ApplicationManager class enables apps to interact with the Application Manager to perform tasks, including:
- Run an app immediately or at a scheduled time.
- Interact with processes, including retrieving the IDs for foreground apps.
- Post global events to the system.
The Application Manager starts an app by getting a new process and spawning a thread within that process to call one of the entry points of the app. For many apps, the main() method of its application class is the single entry point that is called. However, you can configure more than one entry point for an app. Multple entry points allow users to start the app in different ways. For example, if your app allows users to create a new document, you might want to provide users with two icons that they can click to start the app. Users could click one icon to open the app in its home screen and the other icon to open the app in the screen required to create a new document.
Application descriptors are sets of data about an app. A single app can have more than one associated application descriptor. An app that has multiple entry points has an application descriptor corresponding to each of those entry points. You can use the ApplicationDescriptor class to work with application descriptors.
The BlackBerry operating environment is multi-threaded. It enables you to run multiple apps simultaneously. It supports broadcasting events to multiple apps and running background threads.
The event thread is the only thread that can process events and update the UI of the app, so you must not use it to run instructions that could fail or take a long time to complete. If, for example, you need to make a network connection, you must spawn and use another thread.
You may encounter situations where you want to update the UI from a non-event thread. There are two ways to do that:
You can use background threads to access the UI by acquiring the event lock for a short time. This option is useful if you need to perform a quick or urgent UI update. In this case, you must quickly complete the UI update you require and release the lock. Otherwise, your application will become unresponsive and might eventually be terminated by the system. You acquire the event lock by calling Application.getEventLock() on the background thread, and then synchronize this object to serialize access to the UI.
You can add a runnable object to the event queue. This option is preferable if it is acceptable to experience a delay before your task runs. You inject an event in the form of 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 calling its run() method. To inject runnable events in the message queue of your app, use the invokeAndWait() method or the invokeLater() method.
In either case, you should not run tasks that might take a long time to complete or might block. If you use library calls within your task, be sure you understand them well and only use them if they will finish quickly and not block.
One way to terminate an app is to invoke System.exit(), which causes the BlackBerry JVM to terminate all of the processes of the caller and, as a result, all associated threads. Alternatively, you can terminate an app by popping the last screen off the display stack, which causes the close() method to make a call to System.exit().
It is good practice to manually deregister any listeners you registered before terminating your app.
Because you will typically start the event dispatcher thread by calling Application.enterEventDispatcher(), which doesn't terminate, your app should provide a way to terminate. Apps that interact with the user could provide a handler for a Close menu item, and apps that do not interact with the user might terminate upon handling some system event that represents their reason for existence.