ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

The Mobile Information Device Profile and MIDlets, Part 3
Pages: 1, 2

The main consequence of being moved to the Paused state is that the MIDlet no longer has access to the screen; any threads that it created are not automatically terminated, and timers remain active. A MIDlet may choose to terminate any open network connections or background threads and cancel active timers when told to pause, but it is not obliged to do so.

If the host platform decides to resume a paused MIDlet, because the incoming call has terminated, for example, the MIDlet's startApp( ) method is invoked again to notify the MIDlet that it has access to the screen. As a consequence, a MIDlet's startApp( ) method should be written carefully to distinguish, if necessary, between the first time that it is called, which signifies that the MIDlet is being started for the first time, and subsequent calls notifying resumption from the Paused state, to prevent resources from being allocated multiple times. Of course, if a MIDlet reacts to being moved to the Paused state by releasing all of its resources, it would probably be appropriate to execute the same initialization code in startApp( ) to reallocate the resources upon resumption. However, a properly written MIDlet would still take special action in the startApp( ) method to restore the user interface and its internal state to the way it was before it was paused, rather than show the initial screen again.

The fact that the startApp( ) method can be invoked more than once in the lifetime of a MIDlet raises the question of whether initialization should be performed here or in the MIDlet's constructor. The developer is free to choose the more convenient location to allocate resources and prepare the MIDlet's state. In general, resources that will be released in pauseApp( ) should be allocated in startApp( ). Other resources can be allocated in either startApp( ) or the constructor, with care being taken to ensure that allocations performed in startApp( ) are not repeated following resumption from the Paused state.

An important difference between the startApp( ) method and the constructor is that, according to the MIDP specification, the MIDlet is guaranteed to be able to access the Display object that corresponds to the screen (see Chapter 4) only from the point at which startApp( ) is invoked for the first time. Under a strict interpretation of the specification, therefore, initialization that involves a Display object cannot be performed in the constructor. Of course, actual MIDP implementations may not enforce this apparent restriction, but portability may be compromised if the MIDlet accesses the Display object in its constructor.

Related Articles:

The Mobile Information Device Profile and MIDlets, Part 5
This is the final excerpt in a series on MIDP and MIDlets from J2ME in a Nutshell, focusing on the delivery and installation of MIDlets.

The Mobile Information Device Profile and MIDlets, Part 4
In Part 4 of this five-part excerpt from J2ME in a Nutshell, author Kim Topley shows you how to develop MIDlets.

The Mobile Information Device Profile and MIDlets, Part 2
This is the second of a five part book excerpt series based on O'Reilly's J2ME in a Nutshell by Kim Topley. Part 2 focuses on MIDlets and their suites.

The Mobile Information Device Profile and MIDlets, Part 1
This is the first of a five part book excerpt series based on O'Reilly's J2ME in a Nutshell by Kim Topley. Part one is an overview of the Mobile Independent Device Profile and the MIDP Java platform.

A MIDlet may refuse a request to be resumed from the Paused state by throwing a MIDletStateChangeException when its startApp( ) method is called, as described earlier.

When the host platform needs to terminate a MIDlet, it calls the MIDlet's destroyApp( ) method:

public abstract void destroyApp(boolean unconditional) throws

In the destroyApp( ) method, the MIDlet should release all the resources that it has allocated, terminate any background threads, and stop any active timers. When the MIDlet is terminated this way, the unconditional argument has the value true, to indicate that the MIDlet cannot prevent the process from continuing. Under some circumstances, however, it is useful to give the MIDlet the option to not terminate, perhaps because it has data that it needs to save. In this case, the destroyApp( ) method can be invoked with the argument false, in which case the MIDlet can indicate that it wants to continue by throwing a MIDletStateChangeException. The following code illustrates how this technique can be used to implement the conditional shutdown of a MIDlet:

try {
    // Call destroyApp to release resources
    // Arrange for the MIDlet to be destroyed
    notifyDestroyed(  );
} catch (MIDletStateChangeException ex) {
    // MIDlet does not want to close

This code might be used to respond to an Exit button in the MIDlet's user interface. It begins by directly invoking the MIDlet's own destroyApp( ) method so that resources are released. If the MIDlet is not in an appropriate state to terminate, and destroyApp( ) is called with argument false, the MIDlet should throw a MIDletStateChangeException. The calling code should catch this exception and do nothing, as shown here. On the other hand, if the MIDlet is prepared to be terminate, it should complete the destroyApp( ) method normally, in which case the calling code uses the MIDlet notifyDestroyed( ) method to tell the MIDP platform that the MIDlet wants to be terminated.

This example also illustrates the use of the notifyDestroyed( ) method, which is used by a MIDlet to voluntarily terminate. It is important to understand the relationship between the destroyApp( ) and notifyDestroyed( ) methods and when they are used:

  • When the MIDlet is being destroyed by the platform, most likely because the user has requested it, the MIDlet's destroyApp( ) method is called with the argument true, and the MIDlet is destroyed when this method completes. It is not necessary in this case for the MIDlet to invoke its notifyDestroyed( ) method.

  • When the MIDlet itself wants to terminate, typically because it has no more useful work to do or the user has pressed an Exit button, it can do so by invoking its notifyDestroyed( ) method, which tells the platform that it should be destroyed. In this case, the platform does not call the MIDlet's destroyApp( ) method; it assumes that the MIDlet is already prepared to be terminated. Most MIDlets invoke their own destroyApp( ) method to perform the usual tidy up before calling notifyDestroyed( ), as shown earlier.

Note that calling notifyDestroyed( ) is the only way for a MIDlet to terminate voluntarily. MIDlets cannot terminate by calling the System or Runtime exit( ) methods, because these throw a SecurityException.

There are two other methods that a MIDlet may invoke to influence its own lifecycle:

public final void notifyPaused(  );
public final void resumeRequest(  );

The notifyPaused( ) method informs the platform that the MIDlet wishes to be moved to the Paused state; this has the same effect as if the platform had invoked the MIDlet's pauseApp( ) method. When the MIDlet calls notifyPaused( ), the platform does not invoke its pauseApp( ) method, in the same way that it does not call destroyApp( ) in response to notifyDestroyed( ), because it assumes that the MIDlet has prepared itself to be paused. A MIDlet often, therefore, precedes an invocation of notifyPaused( ) with a call to pauseApp( ) so that the appropriate steps are taken before the MIDlet is suspended.

The resumeRequest( ) method is the reverse of notifyPaused( ); it tells the platform that a MIDlet in the Paused state wishes to return to the Active state. At some future time, the platform may resume the MIDlet by calling its startApp( ) method. The resumeRequest( ) method typically is called by a background thread or from a timer that the MIDlet left active while it was paused, an example of which is shown in the next section.

Next time, you learn how to develop MIDlets.

Kim Topley has more than 25 years experience as a software developer and was one of the first people in the world to obtain the Sun Certified Java Developer qualification.

View catalog information for J2ME in a Nutshell

Return to ONJava.com.