MOTODEV // TECHNICAL ARTICLES
Welcome to MOTODEV // Please log in.

MIDlet Lifecycle on Motorola Handsets

Introduction

This document provides information about the MIDlet lifecycle behavior across Motorola's three major Java supported mobile platforms:

  • Motorola OS uses the Motorola Proprietary Operating System
    Motorola OS handsets include MOTORAZR maxx V6, MOTORAZR V3, MOTORAZR V3i, MOTORAZR V3xx, MOTORAZR² V9, MOTOSLVR L9/L72, MOTOSLVR L7i/L7e/L71, V1100, W490, W510, etc.
  • MOTOMAGX uses an embedded Linux Operating System
    For purposes of MIDlet lifecycle behavior, MOTOMAGX handsets are divided into two groups. Throughout the rest of this article, you will see references to Linux OS group 1 handsets and Linux OS group 2 handsets. Here is the definition of which handsets are included in each of these groups:
    • Linux OS group 1: A728, A780, A910, E680i, MOTOMING A1200/e/i/r, MOTOROKR E2, MOTOROKR E6/E6e, MOTORAZR2 V8, MOTOROKR Z6, MOTOMING A1600
    • Linux OS group 2: MOTO U9, MOTO Z6w, MOTOROKR E8
  • Motorola UIQ is based on UIQ technology
    Motorola UIQ handsets include the MOTO Z8 and MOTO Z10.

MIDlet Lifecycle in MIDP 2.0 specification

The JSR-118 Mobile Information Device Profile (MIDP) version 2.0 for Java Micro Edition (Java ME) specification defines the architecture and associated APIs required for development of Java ME applications (MIDlets) that can be run on Motorola mobile handsets. Both Motorola OS and MOTOMAGX handsets follow the specification, but the implementation detail is somewhat different. The text below describes the Active-Paused-Destroyed states and how each state is entered in Motorola OS and MOTOMAGX handsets.

According to the specification, a MIDlet can only have four states:

  • Not running
  • Active
  • Paused
  • Destroyed

A running MIDlet can have three states: active, paused, or destroyed.

Active state

In this state the MIDlet is functioning normally. This state is entered when:

  • Starting the MIDlet application from the device User Interface (UI).
  • The Application Management Software (AMS) calls the MIDlet.startApp() method.
  • In MOTOMAGX handsets (not Motorola OS handsets), the startApp() method is usually called when the MIDlet gets focus.

Paused state

The MIDlet is initialized and is quiescent. The MIDlet should not be holding or using any shared resources. In Motorola OS handsets, the system hangs up the KJava Virtual Machine (KVM) in a paused state. In MOTOMAGX and UIQ handsets, it is the MIDlet's responsibility to stop the threads and release the resources, otherwise the MIDlet continues to execute in the background.

This state is entered in the following ways:

  • From the Active state after the MIDlet.pauseApp() method is called from the AMS (Application Management Software) and returns successfully or the MIDlet.notifyPaused() method returns successfully to the MIDlet.
  • In Motorola OS handsets, paused from a running state by the user pressing the red END key followed by selecting the "Suspend" option from the AMS menu.
  • In MOTOMAGX handsets, the touch screen handsets such as A780, E680i, and MOTOMING A1200 do not have the AMS menu. Only the keypad handsets such as MOTOROKR Z6 and MOTOROKR E2 have the AMS menu. The pauseApp() method is called anytime the MIDlet loses focus on Linux OS group 1 handsets. On Linux OS group 2 handsets, pauseApp() is only called when the user voluntarily moves the MIDlet to the idle state by either closing the flip or pressing the power button and selecting the option "Go to Idle – app running".
  • In UIQ handsets, the pauseApp() method is only called when there is a view switch from one application to other. The pauseApp() method is not called when background applications display permission notifications. An example event causing pauseApp() is pressing the Power key.
  • Paused from a running state by an interruption event such as an incoming phone call on Motorola OS, Linux OS group 1 handsets and on UIQ handsets if the user is switching to that event.

Destroyed state

The MIDlet has released all of its resources and terminated. This state is entered in the following ways:

  • From the Active or Paused state, after the MIDlet.detroyApp() or MIDlet.notifyDestroyed() method is called and returns successfully.
  • In Motorola OS handsets, destroyed from a running state via pressing the red END key followed by selecting "End" from the AMS menu. For MOTOMAGX handsets with the AMS menu, by selecting Close Application.
  • Destroyed from a running state via a user directive from the MIDlet menu.
  • Destroyed from a running state via abnormal MIDlet termination.
  • Destroyed from a suspended state due to device power off.

The MIDlet lifecycle state machine is shown next.

MIDlet lifecycle state machine

Figure 1: MIDlet lifecycle state machine

AMS is a part of the device's operating system software that manages applications. It maintains the MIDlet state and directs the MIDlet through state changes. The startApp(), pauseApp() and destroyApp() methods are only called if the AMS find the state change is necessary for that MIDlet. For example, in the Paused state, the notifyPaused() function will not trigger the pauseApp() function.

Interactivity between Application Management Software (AMS) and MIDlet

Figure 2: Interactivity between Application Management Software (AMS) and MIDlet

MIDlet background execution in MOTOMAGX handsets

By definition, once the pauseApp() method is called, the MIDlet is in the Paused state. Per the MIDP 2.0 specification, a MIDlet "should not be holding or using any shared resources". It is the responsibility of the MIDlet to release unneeded resources when it is "paused". However, since this is a recommended practice and not a mandatory requirement of the specification, a MIDlet may retain resources necessary to allow it to function.

Entering background mode

In the MOTOMAGX handsets, MIDlets are able to run in the background. A MIDlet is informed that it is being placed in the background via the pauseApp() method and hideNotify()/showNotify(). If the MIDlet does not pause itself or release any resources, the MIDlet will continue running in the background. If any resources (such as audio) are needed by a higher priority system function (such as a voice call), the needed resources will be taken away from the MIDlet to service the system requirement. In the MOTOMAGX handsets, the KVM process has lower priority than the native application processes such as the voice call process.

UIQ handsets support multiple executions of MIDlets. At a given time more than one MIDlet can run with one MIDlet running in the foreground and the rest of them running in the background. However, only one instance of an application can run at any given time. When an application is launched, the UIQ application framework makes sure that a new application instance is not created if one is already running.

Background state differences between Motorola OS and MOTOMAGX

In Motorola OS handsets, when a MIDlet is suspended the pauseApp() function is called first, the MIDlet user interface (UI) is hidden and the KJava Virtual Machine (KVM) process is suspended. Any thread and the pauseApp() method in the main MIDlet thread must finish all work in five seconds, otherwise, after five seconds the AMS kills the active thread or, the whole MIDlet thread, respectively. Thus a MIDlet CAN NOT be set to run in the background (without focus) to allow application multi-tasking.

In MOTOMAGX handsets, MIDlets are able to run in the background. A MIDlet is informed that it is being placed in the background via the pauseApp() and hideNotfiy() methods. If the MIDlet does not pause itself or release any resources, the MIDlet continues running in the background. If resources (such as audio) are needed by a higher priority system function (such as a voice call), then the needed resources are taken away from the MIDlet to service the system requirement. In MOTOMAGX handsets, the KVM process has lower priority than the native application processes, such as the voice call process.

In Motorola OS handsets, since the KVM process is suspended in the paused state, the resumeRequest() method can not trigger the startApp() method in background.

In MOTOMAGX handsets, the resumeRequest() method triggers the startApp() method and transfers the MIDlet from paused state to active state.

Below is a counter MIDlet example to illustrate the behavior difference between Motorola OS and MOTOMAGX handsets.

	public void run(){
			//tStart = System.currentTimeMillis();
			if(counter == 0){
				while(continueFlag){
					try{
						
						Thread.sleep(1000);
						counter++;
						siCounter.setText(""+counter);
						 
					}
					catch(Exception e){
							System.out.println(e.toString());
					}
					 
				}	 
		}
	}

In Motorola OS handsets, when the user presses the red END key, the pauseApp() method is called first and the counter value is printed on the form, but after five seconds, the thread is killed by the AMS.

In MOTOMAGX handsets, when the user presses the red END key and selects the option "Go to Idle- app running", the counter keeps updating in the background and when the MIDlet regains focus, the latest value of counter is displayed on the form.

MIDlet background running functionality can be simulated via the emulator in the MOTODEV Studio for Java ME SDK for both Motorola OS and MOTOMAGX handsets. The SDK emulator can simulate network events, such as an incoming call, which generate an interruption and push the MIDlet to paused state. To use this feature, click the emulator title bar and click the Network Events submenu, then choose the Pause option. To exit the pause mode, click again in the Network Events option and choose Resume. As seen in next figure, the counter value was 3 before pausing the MIDlet and after the MIDlet is resumed, the counter value is 41 on MOTOMAGX handsets, meaning the MIDlet continued to run in the background. For an example on this, please check the Counter application accompanying this article.

Simulate MIDlet background running in SDK emulator

Figure 3: Simulate MIDlet background running in SDK emulator

Behavior difference among MOTOMAGX handsets

Linux OS group 1 handsets call pauseApp() whenever the MIDlet UI losses focus due to any event, for example a phone call. But in the Linux OS group 2 handsets, this behavior has been improved by:

  • calling the hideNotify() method when the MIDlet loses focus due to screens from other native applications
  • Calling the showNotify() method when the MIDlet regains focus

In the Linux OS group 2 handsets, pauseApp() is only called when the user manually moves the MIDlet to the pause state by one of following events:

  • closing the flip/slider
  • pressing the END key
  • selecting "go to idle"
Note

NOTE: The idle (power saving) screen that is displayed while the application is running does not cause any hideNotify()/pauseApp() call because the MIDlet is still running and the display has gone dark because there is no user input.

The current behavior for MOTOMAGX handsets is that when the MIDlet is running in the background, the resumeRequest() calls the startApp() but it cannot bring the MIDlet to focus.

Comparing background states between MOTOMAGX and UIQ handsets

UIQ handsets support multiple MIDlets executing at a given time. In both the Motorola OS and MOTOMAGX handsets, only one MIDlet can execute at a time. A user can chose to move one application to the foreground and move the other to background. Therefore, UIQ handsets also support the execution of MIDlets in the background in a manner similar to MOTOMAGX handsets. Here we list a few differences and similarities with MOTOMAGX handsets:

  • hideNotify() is called whenever the Canvas is removed from the display and respectively showNotify() is called when Canvas is made visible. This is the case when the screensaver is displayed (i.e., when the backlight is stopped), when another window shows up in front of the MIDlet (incoming call). This is similar to the behavior observed in Linux OS group 2 MOTOMAGX handsets.
  • pauseApp() is called when there is a view switch between the MIDlet and another application (the MIDlet has completely lost focus, due to other screens). But when there is a partial loss of MIDlet focus pauseApp() is not called. For example if the user receives a phone call, the small phone call notifier screen that is displayed will not cause pauseApp(). But if you answer the phone call, there will be a view switch from the MIDlet to the phone call screen and it will lead to the calling of pauseApp(). Some other example of invocation of pauseApp() are pressing the applications key, pressing the red key or whenever another application takes the focus from the MIDlet. This way the UIQ handsets show similarities with MOTOMAGX handsets in calling pauseApp().

In UIQ handsets when the MIDlet is running in background, resumeRequest() will call startApp() and the MIDlet could be brought to focus if there are no higher priority UI processes running, whereas in several MOTOMAGX handsets it is not possible to bring the MIDlet to focus by calling resumeRequest().

Flip Behaviors in Motorola OS and MOTOMAGX handsets

On Motorola OS handsets it is possible to instruct the AMS to ignore a flip closure/open event and allow a MIDlet to continue to run unaffected by the flip operation. To do this in a Motorola OS device the JAD attribute "FlipInsensitive" can be used and set to "True". The following line can be added to the JAD file:

	FlipInsensitive: True

This behavior is currently not available on the Motorola MOTOMAGX handsets. Support for this behavior is ongoing. Please check the MOTODEV website at http://developer.motorola.com for news on the latest handsets. This means that on MOTOMAGX handsets when the flip is closed the MIDlet will lose focus (it can still be running in the background) and the user will have to bring the focus back to the MIDlet when the flip is reopened. There will be visual indication to the user that the MIDlet is running in the background by way of a coffee cup icon in the status bar at the top of the device screen.

MIDlet development recommendations

A developer should keep background behavior in mind and code a MIDlet to accommodate possible scenarios when applications are competing for resources. One example is an incoming voice call which results in multi media player resources being taken from a running MIDlet and given to the system. Failing to do this correctly will result in a poor user experience or incorrect MIDlet behavior.

Since the MIDP specification was created to support a minimum set of functionality that may or may not support background execution of MIDlets, special care must be taken when implementing a MIDlet designed to run in the background. The recommendations below must be followed closely when developing MIDlets for a MOTOMAGX device considering background state to ensure a good, reliable, user-friendly experience. Since UIQ handsets also support background MIDlet execution, the same recommendations also apply to them.

Pausing a MIDlet if background mode is not needed

For developers of games or other applications that do not have a need or use for background mode execution, we strongly recommended following the guidelines defined in the MIDP 2 specification. Therefore, when the pauseApp()/hideNotify() method is called by the system, the MIDlet MUST pause the game or application, release resources (for example, audio) that are not needed while the game is paused, and take any necessary steps to preserve system or user data. Unlike the Java environment provided by handsets running Motorola's proprietary operating system, the MOTOMAGX handsets and Motorola UIQ handsets do not automatically pause the execution of Java MIDlets based on calling the pauseApp() method. It is the responsibility of the Java developer to stop the execution of the application once the device informs the MIDlet to pause.

On resuming the MIDlet it is therefore necessary to re-instate these resources and any system or user data to the exact same state at the point of suspension in order to give a good user experience. This is done by utilizing the startApp() MIDlet lifecycle method. The MIDlet can then continue its execution cycle.

Utilizing background mode

For developers that wish to make use of background mode on the MOTOMAGX and Motorola UIQ platforms, the MIDlet must be designed with the understanding that a hideNotify() or pauseApp() request will be passed to the MIDlet when the MIDlet is placed in the background. This call can be made due to a number of reasons such as incoming voice calls or flip/slider closure. The user can also manually put the application in the background by pressing the red END key and selecting the option from the native pop-up menu to return to IDLE with the MIDlet running. The pauseApp() method is called once the background execution (idle) option is selected.

A MIDlet intended to run in the background must respond to hideNotify()/showNotify() and pauseApp()/startApp() method calls as defined in the MIDP 2.0 specification, but can continue to utilize the resources needed to perform necessary functions in the background. Since the MIDlet is in the paused state once it responds to the pauseApp() method, it is highly recommended that any unnecessary processing, such as displaying updates, be stopped. This provides a better overall user experience on the handset.

The startApp() method is called to bring the MIDlet back to the Active state. When this method call is received, the MIDlet should request any necessary resources, resume updates to the display, and continue executing in the foreground of the device.

It should be noted that Linux OS group 1 handsets and newer handsets using High Level Screen APIs, pauseApp()/startApp() should be used for background mode. For applicatios using Low Level Screen APIs (Canvas/GameCanvas) on Linux OS group 2 handsets, hideNotify()/showNotify() should be used in addition to pauseApp()/startApp(). In order to avoid repeated calls, check to see whether or not the MIDlet state is paused. If the MIDlet is in a paused state, then code in hideNotify() and showNotify() should not be executed.

Audio resource handling

Executing in background mode does not guarantee availability of audio resources. If a higher priority task occurs on the handset, such as a phone call made or received, the audio resources will be taken away from other applications. The system informs the MIDlet that the audio is unavailable via a DEVICE_UNAVAILABLE event. The MIDlet is informed when audio resources are made available again via a DEVICE_AVAILABLE event. The MIDlet should be able to process the event and take necessary actions to provide an optimal user experience. This could include pausing and restarting audio, stopping streaming audio, or replaying notifications once the audio resources are available again.

If the MIDlet is not concerned with the loss of audio resources while in background mode, it is highly recommended that the MIDlet re-request audio resources once the MIDlet is placed back into the active state (startApp() method is called) or brought to focus (showNotify() is called). This should be done even if the audio resources were available at the time when the pauseApp() method was called.

If audio resources are not available when the MIDlet starts, it is the responsibility of the MIDlet to provide any error messages to the user and/or terminate.

Network resource handling

Executing in background mode does not guarantee availability of network resources. If network resources are lost for any reason, while the MIDlet is executing in the background, an exception will be thrown when the MIDlet attempts to read or write over the lost connection.

Threads

Many MIDlet developers create multi-threaded MIDlets. These threads can be used to control a network connection, a media player, a canvas, etc. Depending on the functionality when entering the background state, any threads additional to the main MIDlet thread can be stopped. Also, when leaving the background state to the foreground state, any stopped threads should be restarted again. This can be done by toggling a background running flag in the lifecycle methods pauseApp()/startApp() and/or hideNotify()/showNotify() and then testing for this flag in the thread loop. See the example below. For Linux OS group 1 handsets and Linux OS group 2 handsets using High Level Screen APIs, pauseApp()/startApp() should be used. For applications using Low Level Screen APIs (Canvas/GameCanvas) on Linux OS group 2 handsets, hideNotify()/showNotify() should be used in addition to pauseApp()/startApp(). In order to avoid repeated calls, the MIDlet state should be checked to see if it is in a paused state or not. If the MIDlet is in paused state, then code in hideNotify() and showNotify() should not be executed. For an example on this, please check the MusicPlayer application accompanying this article.

Thread_Run() {
    While(true) {
        If (is_in_background) {
            Wait(); // waiting for notification to wake up
        }
        …
    }
}

Alternatively, the same background running flag can be used so the thread can be slowed to unload the CPU as follows:

Thread_Run() {
    While(true) {
        If (is_in_background) {
            Sleep(1000); // manually slow the thread and unload the CPU
        }
        …
    }
}

Timer tasks

The TimerTask is often used by games developers and since it implements the Runnable Interface, we recommend that you suspend/cancel the object when using the lifecycle method pauseApp()/hideNotify(). The TimerTask object can be restarted in the lifecycle method startApp() or showNotify() as follows.

pauseApp() {
    ...
    working_timer.cancel(); //cancel task, renew when startApp() is called
    ...
}	

Alternatively, the TimerTask can be rescheduled for some later time thus relieving the CPU of work.

pauseApp() {
    ...
    working_timer.schedule( timertask, delay, LONGER_PERIOD); 
    // re-schedule the timer with long period to unload the CPU 
    ...
}

Record Management Store

MIDlets often store "persistent" data in the Record Management Store (RMS). This data is game information that the MIDlet must not lose between invocations such as a high score table or game state. In the event of an abnormal MIDlet termination when in background running mode, it is recommended that the RMS is closed and resources are released when a MIDlet enters a paused state. These resources should then be reallocated when they are needed by the MIDlet or when the MIDlet leaves the paused state and returns to a normal running state.

MOTOMAGX best practices example

A Music Player example is provided to illustrate how to use the background execution feature in MOTOMAGX and Motorola UIQ handsets. In this example, the MIDlet can select to play the music in background or not. The UI thread and music player thread are independent of the MIDlet main thread and the DEVICE_AVAILABLE and DEVICE_UNAVAILABLE events are handled correctly. Also note the usage of hideNotify()/showNotify() and pauseApp()/startApp() to control the threads and reset flags which indicate MIDlet states. To take care of the situation in newer Linux OS group 2 handsets which support the use of hideNotify()/showNotify() for background notification and also for Motorola UIQ handsets, we have used the flags isHideCodeExc and isDisplayCodeExc to make sure that only code in hideNotify() or pauseApp() gets executed at a time and only the code in showNotify() or startApp() gets executed at a time. We don't want the same code that is present in both the hideNotify() and pauseApp() and showNotify() and startApp() to execute at a given time when the user manually moves the VM in background.

Music Player example for utilizing background mode

Figure 4: Music Player example for utilizing background mode

Potential conflicts

Many MIDlet developers use methods that could cause potential conflicts.

  • The showNotify() and hideNotify() methods to control pause/suspend behavior of MIDlets utilizing a Canvas or GameCanvas.
  • The Displayable.isShown() method to determine if a Form or TextBox object is visible to the user.

These methods can be used by the developer to control the MIDlet with respect to lifecycle states but care must be taken to ensure that there are no resource conflicts introduced between the pauseApp() and hideNotify() methods and the startApp() and showNotify() methods.

  • Often pauseApp() is used to deallocate resources and objects as is hideNotify().
  • Subsequently, startApp() is used to reallocate resources and objects as is showNotify().

Conclusion

In this article we discussed the MIDlet lifecycle implementations across Motorola OS, MOTOMAGX and UIQ handsets. MOTOMAGX and UIQ handsets have different MIDlet lifecycle implementation as compared to Motorola OS handsets. They give more flexible design to application developers by supporting background execution. However recommended practices described in the article should be reviewed by developers before developing applications for these handsets.

References

Back to Top
Was This Document Helpful?
Yes  No 

Additional Comments (Optional)