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


AddThis Social Bookmark Button O'Reilly Book Excerpts: J2ME in a Nutshell

The MIDP and MIDlets, Part 3

by Kim Topley

All MIDlets are derived from the abstract base class javax.microedition.midlet.MIDlet, which contains methods that the MIDP platform calls to control the MIDlet's lifecycle, as well as methods that the MIDlet itself can use to request a change in its state. A MIDlet must have a public default constructor (that is, a constructor that requires no arguments), which may be one supplied by the developer if there is any initialization to perform or, when there are no explicit constructors, the empty default constructor inserted by the Java compiler. This is what a skeleton MIDlet class might look like:

public class MyMIDlet extends MIDlet {
    // Optional constructor
    MyMIDlet(  ) {
    protected void startApp(  ) throws MIDletStateChangedException {
    protected void pauseApp(  ) {
    protected void destroyApp(boolean unconditional) 
                              throws MIDletStateChangedException {

At any given time, a MIDlet is in one of three states: Paused, Active, or Destroyed. A state diagram that shows how these states are related and the legal state transitions is shown in Figure 3-4.

Figure 3-4. The lifecycle of a MIDlet.

When a MIDlet is loaded, it is initially in the Paused state. The usual class and instance initialization is then performed--that is, static initializers are called the first time the MIDlet class is loaded, all instance initializers are invoked when the MIDlet instance is created, and its public, no-argument constructor is then invoked. If the MIDlet throws an exception during the execution of its constructor, the MIDlet is destroyed. If the MIDlet does not throw an exception, it is scheduled for execution at some later time. Its state is changed from Paused to Active, and its startApp( ) method is called. The MIDlet class declares this method as follows:

protected void startApp(  ) throws MIDletStateChangeException;

That this method is abstract means that you must implement it in your MIDlet, and that it is protected implies that it will be called either from the MIDlet class itself or from another class in the javax.microedition.midlet package. In the reference implementation, the MIDlet lifecycle methods are called from a class in this package called Scheduler, but there is nothing in the MIDP specification that requires this class be used. Licensees may provide their own scheduler implementations, provided that it supports the MIDlet lifecycle as described in this section. It is very common for MIDlet developers to redefine the startApp( ) method as public, which is certainly a safe option, but this should not be necessary because vendor implementations must continue to work even if these methods are declared as protected.

J2ME in a Nutshell

Related Reading

J2ME in a Nutshell
By Kim Topley

The startApp( ) method may complete normally, in which case the MIDlet is allowed to run, or it may inform the MIDP platform that the MIDlet does not want to run at this point. There are several ways to achieve the latter:

  • If the startApp( ) method detects an error condition that stops it from completing, but which might not exist later (i.e., a transient error condition), it should throw a MIDletStateChangeException. This moves the MIDlet back to the Paused state, so that another attempt to start it can be made later.

  • If the startApp( ) method detects an error condition from which recovery is likely never to be possible (a nontransient error condition), it should call its notifyDestroyed( ) method, which is described a little later.

  • Finally, the MIDlet may throw an exception other than MIDletStateChangeException, either deliberately or because a method that it invokes throws the exception, and the startApp( ) method does not catch it. In this case, it is assumed that a fatal error has occurred, and the MIDlet is destroyed by calling its destroyApp( ) method (described later).

If the MIDlet does none of these things, it is in the Active state and will be allowed to run until it is either paused or destroyed. A MIDlet returns after completing its startApp( ) method, and it does not have a method that contains the main logic to which control could be passed, so where is the MIDlet's code placed? Usually, a MIDlet has a user interface and executes code as a result of events generated by key presses or pointer movements. MIDlets can also start separate background threads to run code that does not depend on the user interface, or they can use a timer to schedule work periodically, as will be shown later. If you take these approaches, it is important to manage the background threads and/or timers appropriately when the MIDlet itself is paused or destroyed.

At any time, the MIDP platform can put a MIDlet into the Paused state. On a cell phone, for example, this might happen when the host software detects an incoming call and needs to release the phone's display so the user can answer the call. When a MIDlet is paused, its pauseApp( ) method is called:

protected abstract void pauseApp(  );

As with startApp( ), a MIDlet is required to provide an implementation for this method. The appropriate response to this state change depends on the MIDlet itself, but, in general, it should release any resources it is holding and save the current state so it can restore itself when it is reactivated later.

Pages: 1, 2

Next Pagearrow