MIDP MIDlet Lifecycle

The MIDlet package defines Mobile Information Device Profile applications and the interactions between the application and the environment in which the application runs. An application of the Mobile Information Device Profile is a `MIDlet`.

## Applications

The MIDP defines an application model to allow the limited resources of the device to be shared by multiple MIDP applications, or MIDlets. It defines what a MIDlet is, how it is packaged, what runtime environment is available to the MIDlet, and how it should be behave so that the device can manage its resources. The application model defines how multiple MIDlets forming a suite can be packaged together and share resources within the context of a single Java Virtual Machine. Sharing is feasible with the limited resources and security framework of the device since they are required to share class files and to be subject to a single set of policies and controls.

### MIDP MIDlet Suite

A MIDP application MUST use only functionality specified by the MIDP specification as it is developed, tested, deployed, and run.

The elements of a MIDlet suite are:

- Runtime execution environment
- MIDlet suite packaging
- Application descriptor
- Application lifecycle

Each device is presumed to implement the functions required by its users to install, select, run, and remove MIDlets. The term application management software is used to refer collectively to these device specific functions. The application management software provides an environment in which the MIDlet is installed, started, stopped, and uninstalled. It is responsible for handling errors during the installation, execution, and removal of MIDlet suites and interacting with the user as needed. It provides to the MIDlet(s) the Java runtime environment required by the MIDP Specification.

One or more MIDlets MAY be packaged in a single JAR file. Each MIDlet consists of a class that extends the `MIDlet` class and other classes as may be needed by the MIDlet. The manifest in the JAR file contains attributes that are used during installation and execution of MIDlets. The MIDlet is the entity that is launched by the application management software. When a MIDlet suite is invoked, a Java Virtual Machine is needed on which the classes can be executed. A new instance of the MIDlet is created by the application management software and used to direct the MIDlet to start, pause, and destroy itself.

Sharing of data and other information between MIDlets is controlled by the individual APIs and their implementations. For example, the Record Management System API specifies the methods that are used when the record stores associated with a MIDlet suite are shared among MIDlets.

## MIDlet Suite Security

The MIDP 1.0 specification constrained each MIDlet suite to operate in a sandbox wherein all of the APIs available to the MIDlets would prevent access to sensitive functions of the device. That sandbox concept is used in this specification and all untrusted MIDlet suites are subject to its limitations. Every implementation of this specification MUST support running untrusted MIDlet suites.

MIDP introduces the concept of trusted applications that may be permitted to use APIs that are considered sensitive and are restricted. If and when a device determines that a MIDlet suite can be trusted the device allows access as indicated by the policy. Security for MIDP Applications section describes the concepts and capabilities of untrusted and trusted applications.

### MIDP Execution Environment

The MIDP defines the execution environment provided to MIDlets. The execution environment is shared by all MIDlets within a MIDlet suite, and any MIDlet can interact with other MIDlets packaged together. The application management software initiates the applications and makes the following available to the MIDlet:

- Classes and native code that implement the CLDC, including a Java Virtual Machine
- Classes and native code that implement the MIDP runtime
- All classes from a single JAR file for execution
- Non-class files from a single JAR file as resources
- Contents of the descriptor file, when it is present
- Any other APIs available on the device such as implementations of additional JSRs, Licensee Open Classes, Optional Packages, etc.

The CLDC and Java Virtual Machine provide multi-threading, locking and synchronization, the execution of byte codes, dispatching of methods, etc. A single VM is the scope of all policy, naming, and resource management. If a device supports multiple VMs, each may have its own scope, naming, and resource management policies. MIDlet Suites MUST NOT contain classes that are in packages defined by the CLDC or MIDP.

The MIDP provides the classes that implement the MIDP APIs. The implementation MUST ensure that the application programmer cannot override, modify, or add any classes to these protected system packages.

A single JAR file contains all of the MIDlet's classes. The MIDlet may load and invoke methods from any class in the JAR file, in the MIDP, or in the CLDC. All of the classes within these three scopes are shared in the execution environment of the MIDlets from the JAR file. All states accessible via those classes are available to any Java class running on behalf of the MIDlet. There is a single space containing the objects of all MIDlets, MIDP, and CLDC in use by the MIDlet suite. The usual Java locking and synchronization primitives SHOULD be used when necessary to avoid concurrency problems. Each library will specify how it handles concurrency and how the MIDlet should use it to run safely in a multi-threaded environment.

The class files of the MIDlet are only available for execution and can neither be read as resources nor extracted for re-use. The implementation of the CLDC may store and interpret the contents of the JAR file in any manner suitable.

The files from the JAR file that are not Java class files are made available using `java.lang.Class.getResourceAsStream`. For example, the manifest would be available in this manner.

The contents of the MIDlet descriptor file, when it is present, are made available via the `javax.microedition.midlet.MIDlet.getAppProperty` method.

### MIDlet Suite Packaging

One or more MIDlets are packaged in a single JAR file that includes:

- A manifest describing the contents
- Java classes for the MIDlet(s) and classes shared by the MIDlets
- Resource files used by the MIDlet(s)

The developer is responsible for creating and distributing the components of the JAR file as appropriate for the target user, device, network, locale, and jurisdiction. For example, for a particular locale, the resource files would be tailored to contain the strings and images needed for that locale.

The JAR manifest defines attributes that are used by the application management software to identify and install the MIDlet suite and as defaults for attributes not found in the application descriptor. The attributes are defined for use in both the manifest and the optional application descriptor.

The predefined attributes listed below allow the application management software to identify, retrieve, install, and invoke the MIDlet.

###### MIDlet Attributes

Attribute Name | Attribute Description
--- | ---
MIDlet-Name | The name of the MIDlet suite that identifies the MIDlets to the user.
MIDlet-Version | The version number of the MIDlet suite. Version numbers are formatted so they can be used by the application management software for install and upgrade uses, as well as communication with the user.
MIDlet-Vendor | The organization that provides the MIDlet suite.
MIDlet-Icon | The case-sensitive absolute name of a PNG file within the JAR used to represent the MIDlet suite. It SHOULD be used when the Application Management Software displays an icon to identify the suite.
MIDlet-Description | The description of the MIDlet suite.
MIDlet-Info-URL | A URL for information further describing the MIDlet suite. The syntax and meaning MUST conform to RFC2396 and RFCs that define each scheme.
MIDlet-<n> | The name, icon, and class of the nth MIDlet in the JAR file separated by a comma. The lowest value of <n> MUST be 1 and consecutive originals MUST be used. The first missing entry terminates the list. Any additional entries are ignored. Leading and trailing spaces in name, icon and class are ignored. Name is used to identify this MIDlet to the user. The name must be present and be non-null. Icon is the case-sensitive absolute path name of an image (PNG) within the JAR for the icon of the nth MIDlet. The icon may be omitted. Class is the name of the class extending the `javax.microedition.midlet.MIDlet` class for the nth MIDlet. The classname MUST be non-null and contain only characters for Java class names. The class MUST have a public no-args constructor. The class name IS case sensitive.
MIDlet-Jar-URL | The URL from which the JAR file can be loaded. The syntax and meaning MUST conform to RFC2396 and RFCs that define each scheme. Both absolute and relative URLs MUST be supported. The context for a relative URL is the URL from which this application descriptor was loaded.
MIDlet-Jar-Size | The number of bytes in the JAR file.
MIDlet-Data-Size | The minimum number of bytes of persistent data required by the MIDlet. The device may provide additional storage according to its own policy. The default is zero.
MicroEdition-Profile | The J2ME profiles required, using the same format and value as the System property `microedition.profiles` (for example "MIDP-2.1"). The device must implement all of the profiles listed. If any of the profiles are not implemented the installation MUST fail. Multiple profiles are separated with a blank (Unicode U+0020).
MicroEdition-Configuration | The J2ME Configuration required using the same format and value as the System property `microedition.configuration` (for example "CLDC-1.0").
MIDlet-Permissions | Zero or more permissions that are critical to the function of the MIDlet suite. See the MIDlet Suite Security section for details of usage.
MIDlet-Permissions-Opt | Zero or more permissions that are non-critical to the function of the MIDlet suite. See the MIDlet Suite Security section for details of usage.
MIDlet-Push-<n> | Register a MIDlet to handle inbound connections. Refer to javax.microedition.io.PushRegistry for details.
MIDlet-Install-Notify | Refer to the OTA Specification for details.
MIDlet-Delete-Notify | Refer to the OTA Specification for details.
MIDlet-Delete-Confirm | Refer to the OTA Specification for details.

Some attributes use multiple values, for those attributes the values are separated by a comma (Unicode U+002C) except where noted. Leading and trailing whitespace (Unicode U+0020) and tab (Unicode U+0009) are ignored on each value.

#### Version Numbering

Version numbers have the format Major.Minor[.Micro] (X.X[.X]), where the .Micro portion MAY be omitted. (If the .Micro portion is not omitted, then it defaults to zero). In addition, each portion of the version number is allowed a maximum of two decimal digits (i.e., 0-99). Version numbers are described in the the Java(TM) Product Versioning Specification http://java.sun.com/products/jdk/1.2/docs/guide/versioning/spec/VersioningSpecification.html.

For example, 1.0.0 can be used to specify the first version of a MIDlet suite. For each portion of the version number, leading zeros are not significant. For example, 08 is equivalent to 8. Also, 1.0 is equivalent to 1.0.0. However, 1.1 is equivalent to 1.1.0, and not 1.0.1.

A missing MIDlet-Version tag is assumed to be 0.0.0, which means that any non-zero version number is considered as a newer version of the MIDlet suite.

#### JAR Manifest

The manifest provides information about the contents of the JAR file. JAR file formats and specifications are available at http://java.sun.com/products/jdk/1.2/docs/guide/jar/index.html. Refer to the JDK JAR and manifest documentation for the syntax and related details. MIDP implementations MUST implement handling of lines longer than 72 bytes as defined in the manifest specification. An attribute MUST not appear more than once within the manifest. If an attribute is duplicated the effect is unspecified. Manifest attributes are passed to the MIDlet when requested using the `MIDlet.getAppProperty` method, unless the attribute is duplicated in the application descriptor, for handling of duplicate attributes see the "Application Descriptor" section.

The manifest MUST contain the following attributes:

- MIDlet-Name
- MIDlet-Version
- MIDlet-Vendor

The manifest or the application descriptor MUST contain the following attributes:

- MIDlet-<n> for each MIDlet
- MicroEdition-Profile
- MicroEdition-Configuration

The manifest MAY contain the following:

- MIDlet-Description
- MIDlet-Icon
- MIDlet-Info-URL
- MIDlet-Data-Size
- MIDlet-Permissions
- MIDlet-Permissions-Opt
- MIDlet-Push-<n>
- MIDlet-Install-Notify
- MIDlet-Delete-Notify
- MIDlet-Delete-Confirm
- Any application-specific attributes that do not begin with `MIDlet-` or `MicroEdition-`

For example, a manifest for a hypothetical suite of card games would look like the following example:

      MIDlet-Name: CardGames
      MIDlet-Version: 1.1.9
      MIDlet-Vendor: CardsRUS
      MIDlet-1: Solitaire, /Solitare.png, org.cardsrus.games.Solitare
      MIDlet-2: JacksWild, /JacksWild.png, org.cardsrus.games.JacksWild
      MicroEdition-Profile: MIDP-2.1
      MicroEdition-Configuration: CLDC-1.0
      Solitaire-Author: John Q. Public

#### MIDlet Classes

All Java classes needed by the MIDlet are be placed in the JAR file using the standard structure, based on mapping the fully qualified class names to directory and file names. Each period is converted to a forward slash ( / ) and the `.class` extension is appended. For example, a class `com.sun.microedition.Test` would be placed in the JAR file with the name `com/sun/microedition/Test.class` .

### Application Descriptor

Each JAR file MAY be accompanied by an application descriptor. The application descriptor is used in conjunction with the JAR manifest by the application management software to manage the MIDlet and is used by the MIDlet itself for configuration specific attributes. The descriptor allows the application management software on the device to verify that the MIDlet is suited to the device before loading the full JAR file of the MIDlet suite. It also allows configuration-specific attributes (parameters) to be supplied to the MIDlet(s) without modifying the JAR file.

To allow devices to dispatch an application descriptor to the MIDP application management software, a file extension and MIME type are registered with the IANA:

- The file extension of an application descriptor file is `jad`
- The MIME type of an application descriptor file is
  `text/vnd.sun.j2me.app-descriptor`.

A predefined set of attributes is specified to allow the application management software to identify, retrieve, and install the MIDlet(s). All attributes appearing in the descriptor file are made available to the MIDlet(s). The developer may use attributes not beginning with `MIDlet-` or `MicroEdition-` for application-specific purposes. Attribute names are case-sensitive and MUST match exactly. An attribute MUST NOT appear more than once within the manifest. If an attribute is duplicated the effect is unspecified. The MIDlet retrieves attributes by name by calling the `MIDlet.getAppProperty` method.

The application descriptor MUST contain the following attributes:

- MIDlet-Name
- MIDlet-Version
- MIDlet-Vendor
- MIDlet-Jar-URL
- MIDlet-Jar-Size

The application descriptor MAY contain:

- MIDlet-<n> for each MIDlet
- MicroEdition-Profile
- MicroEdition-Configuration
- MIDlet-Description
- MIDlet-Icon
- MIDlet-Info-URL
- MIDlet-Data-Size
- MIDlet-Permissions
- MIDlet-Permissions-Opt
- MIDlet-Push-<n>
- MIDlet-Install-Notify
- MIDlet-Delete-Notify
- MIDlet-Delete-Confirm
- Any application-specific attributes that do not begin with `MIDlet-` or `MicroEdition-`

The mandatory attributes MIDlet-Name, MIDlet-Version, and MIDlet-Vendor MUST be duplicated in the descriptor and manifest files since they uniquely identify the application. If they are not identical (not from the same application), then the JAR MUST NOT be installed.

Duplication of other manifest attributes in the application descriptor is not required and their values MAY differ even though both the manifest and descriptor files contain the same attribute for untrusted MIDlet suites. If the MIDlet suite is not trusted the value from the descriptor file will override the value from the manifest file. If the MIDlet suite is trusted then the values in the application descriptor MUST be identical to the corresponding attribute values in the Manifest.

MIDlets MUST NOT add any attributes to the manifest or the Application Descriptor that start with `MIDlet-` or `MicroEdition-` other than those defined in the relevant Configuration and Profiles (e.g. CLDC and MIDP) specifications. Unrecognized attributes MUST be ignored by the AMS.

Generally speaking, the format of the application descriptor is a sequence of lines consisting of an attribute name followed by a colon, the value of the attribute, and a carriage return. White space is ignored before and after the value. The order of the attributes is arbitrary.

The application descriptor MAY be encoded for transport or storage and MUST be converted to Unicode before parsing, using the rules below. For example, an ISO-8859-1 encoded file would need to be read through the equivalent of `java.io.InputStreamReader` with the appropriate encoding. The default character encoding for transporting a descriptor is UTF-8. Descriptors retrieved via HTTP, if that is supported, SHOULD use the standard HTTP content negotiation mechanisms, such as the Content-Encoding header and the Content-Type charset parameter to convert the stream to UCS-2.

BNF for Parsing Application Descriptors

     appldesc:  *attrline
     attrline:  attrname ":" [WSP] attrvalue [WSP] newlines
     attrname:  1*<any Unicode char except
                     CTLs or separators>
     attrvalue: *valuechar | valuechar *(valuechar | WSP) valuechar
     valuechar: <any valid Unicode character,
                excluding CTLS and WSP>
     newlines = 1*newline  ; allow blank lines to be ignored
     newline:   CR LF | LF

     CR  = <Unicode carriage return (U+000D)>
     LF  = <Unicode linefeed (U+000A)>

     WSP:  1*( SP | HT )
     SP  = <Unicode space (U+0020)>
     HT  = <Unicode horizontal-tab (U+0009)>
     CTL = <Unicode characters
               U+0000 - U+001F and U+007F>
     separators: "(" | ")" | "<" |
                 ">" | "@" |
                 "," | ";" | ":" |
                 "'" | <">|
                 "/" | "[" | "]" |
                 "?" | "=" |
                 "{" | "}" | SP | HT

For example, an application descriptor for a hypothetical suite of card games would look look like the following example:

     MIDlet-Name: CardGames
     MIDlet-Version: 1.1.9
     MIDlet-Vendor: CardsRUS
     MIDlet-1: Solitaire, /Solitare.png, com.cardsrus.org.Solitare
     MIDlet-2: JacksWild, /JacksWild.png, com.cardsrus.org.JacksWild
     MicroEdition-Profile: MIDP-2.1
     MicroEdition-Configuration: CLDC-1.0
     MIDlet-Description: Really cool card games
     MIDlet-Jar-URL: http://www.cardsrus.com/games/cardgames.jar
     MIDlet-Jar-Size: 7378
     MIDlet-Data-Size: 256

### Application Lifecycle

Each MIDlet MUST extend the `MIDlet` class. The `MIDlet` class allows for the orderly starting, stopping, and cleanup of the MIDlet. The MIDlet can request the arguments from the application descriptor to communicate with the application management software. A MIDlet suite MUST NOT have a `public static void main()` method. If it exists, it MUST be ignored by the application management software. The application management software provides the initial class needed by the CLDC to start a MIDlet.

When a MIDlet suite is installed on a device, its classes, resource files, arguments, and persistent storage are kept on the device and ready for use. The MIDlet(s) are available to the user via the device's application management software.

When the MIDlet is run, an instance of the MIDlet's primary class is created using its public no-argument constructor, and the methods of the `MIDlet` are called to sequence the MIDlet through its various states. The MIDlet can either request changes in state or notify the application management software of state changes via the `MIDlet` methods. When the MIDlet is finished or terminated by the application management software, it is destroyed, and the resources it used can be reclaimed, including any objects it created and its classes. The MIDlet MUST NOT call `System.exit` , which will throw a `SecurityException` when called by a MIDlet.

The normal states of Java classes are not affected by these classes as they are loaded. Referring to any class will cause it to be loaded, and the normal static initialization will occur.

Class in `javax.microedition.midlet` | Description
--- | ---
`MIDlet` | Extended by a MIDlet to allow the application management software to start, stop, and destroy it.
`MIDletStateChangeException` | Thrown when the application cannot make the change requested.

### MIDlet lifecycle

The `MIDlet` lifecycle defines the protocol between a `MIDlet` and its environment through the following:

- A simple well-defined state machine

- A concise definition of the MIDlet's states

- APIs to signal changes between the states

## MIDlet Lifecycle Definitions

The following definitions are used in the `MIDlet` lifecycle:

- application management software - a part of the device's software operating environment that manages `MIDlets`. It maintains the MIDlet state and directs the `MIDlet` through state changes.

- `MIDlet` - a MIDP application on the device. The `MIDlet` can signal the application management software about whether is it wants to run or has completed. A `MIDlet` has no knowledge of other `MIDlet`s through the `MIDlet` API.

- `MIDlet` States - the states a `MIDlet` can have are defined by the transitions allowable through the `MIDlet` interface. More specific application states are known only to the application.

## MIDlet States

The `MIDlet` state machine is designed to ensure that the behavior of an application is consistent and as close as possible to what device manufactures and users expect, specifically:

- The perceived startup latency of an application SHOULD be very short.

- It SHOULD be possible to put an application into a state where it is not active.

- It SHOULD be possible to destroy an application at any time.

The valid states for `MIDlet`s are:

State Name | Description
--- | ---
Paused | The `MIDlet` is initialized and is quiescent. It SHOULD not be holding or using any shared resources. This state is entered: After the `MIDlet` has been created using `new`. The public no-argument constructor for the `MIDlet` is called and returns without throwing an exception. The application typically does little or no initialization in this step. If an exception occurs, the application immediately enters the Destroyed state and is discarded. From the Active state after the `MIDlet.pauseApp()` method is called from the AMS and returns successfully. From the Active state when the `MIDlet.notifyPaused()` method returns successfully to the `MIDlet`. From the Active state if `startApp` throws an `MIDletStateChangeException`.
Active | The `MIDlet` is functioning normally. This state is entered: Just prior to the AMS calling the `MIDlet.startApp()` method.
Destroyed | The `MIDlet` has released all of its resources and terminated. This state is entered: When the AMS called the `MIDlet.destroyApp()` method and returns successfully, except in the case when the `unconditional` argument is false and a `MIDletStateChangeException` is thrown. The `destroyApp()` method shall release all resources held and perform any necessary cleanup so it may be garbage collected. When the `MIDlet.notifyDestroyed()` method returns successfully to the application. The `MIDlet` must have performed the equivalent of the `MIDlet.destroyApp()` method before calling `MIDlet.notifyDestroyed()`. Note: This state is only entered once.

The states and transitions for a `MIDlet` are:

## MIDlet Lifecycle Model

A typical sequence of `MIDlet` execution is:

Application Management Software | `MIDlet`
--- | ---
The application management software creates a new instance of a `MIDlet`. | The default (no argument) constructor for the `MIDlet` is called; it is in the Paused state.
The application management software has decided that it is an appropriate time for the `MIDlet` to run, so it calls the `MIDlet.startApp` method for it to enter the Active state. | The `MIDlet` acquires any resources it needs and begins to perform its service.
The application management software wants the MIDlet to significantly reduce the amount of resources it is consuming, so that they may temporarily be used by other functions on the device such as a phone call or running another MIDlet. The AMS will signal this request to the MIDlet by calling the `MIDlet.pauseApp` method. The MIDlet should then reduce its resource consumption as much as possible. | The `MIDlet` stops performing its service and might choose to release some resources it currently holds.
The application management software has determined that the `MIDlet` is no longer needed, or perhaps needs to make room for a higher priority application in memory, so it signals the `MIDlet` that it is a candidate to be destroyed by calling the `MIDlet.destroyApp` method. | If it has been designed to do so, the `MIDlet` saves state or user preferences and performs clean up.

## MIDlet Interface

- `pauseApp` - the `MIDlet` SHOULD release any temporary resources and become passive

- `startApp` - the `MIDlet` SHOULD acquire any resources it needs and resume

- `destroyApp` - the `MIDlet` SHOULD save any state and release all resources

- `notifyDestroyed` - the `MIDlet` notifies the application management software that it has cleaned up and is done

- `notifyPaused` - the `MIDlet` notifies the application management software that it has paused

- `resumeRequest` - the `MIDlet` asks application management software to be started again

- `getAppProperty` - gets a named property from the `MIDlet`

## Application Implementation Notes

The application SHOULD take measures to avoid race conditions in the execution of the `MIDlet` methods. Each method may need to synchronize itself with the other methods avoid concurrency problems during state changes.

## Example MIDlet Application

The example uses the MIDlet lifecycle to do a simple measurement of the speed of the Java Virtual Machine.

    import javax.microedition.midlet.*;

    /**
     * An example MIDlet runs a simple timing test
     * When it is started by the application management software it will
     * create a separate thread to do the test.
     * When it finishes it will notify the application management software
     * it is done.
     * Refer to the startApp, pauseApp, and destroyApp
     * methods so see how it handles each requested transition.
     */
    public class MethodTimes extends MIDlet implements Runnable {
        // The state for the timing thread.
        Thread thread;

        /**
         * Start creates the thread to do the timing.
         * It should return immediately to keep the dispatcher
         * from hanging.
         */
        public void startApp() {
            thread = new Thread(this);
            thread.start();
        }

        /**
         * Pause signals the thread to stop by clearing the thread field.
         * If stopped before done with the iterations it will
         * be restarted from scratch later.
         */
        public void pauseApp() {
            thread = null;
        }

        /**
         * Destroy must cleanup everything.  The thread is signaled
         * to stop and no result is produced.
         */
        public void destroyApp(boolean unconditional) {
            thread = null;
        }

       /**
         * Run the timing test, measure how long it takes to
         * call a empty method 1000 times.
         * Terminate early if the current thread is no longer
         * the thread from the
         */
        public void run() {
            Thread curr = Thread.currentThread();  // Remember which thread is current
            long start = System.currentTimeMillis();
            for (int i = 0; i < 1000000 && thread == curr; i++) {
                empty();
            }
            long end = System.currentTimeMillis();

            // Check if timing was aborted, if so just exit
            // The rest of the application has already become quiescent.
            if (thread != curr) {
                return;
            }
            long millis = end - start;
            // Reporting the elapsed time is outside the scope of this example.

            // All done cleanup and quit
            destroyApp(true);
            notifyDestroyed();
        }

        /**
         * An Empty method.
         */
        void empty() {
        }
    }

@since MIDP 1.0