J2ME Guide – Part 2

In the first module we introduced MIDP2.0 fundamental concepts. We talked about Configuration, Profile and Optional Packages. In this module we start programming our first midlet and studing the midlet lifecycle in detail. We’ll end with some useful methods in order to create a simple Alert MIDlet. From now on, with midlet we’ll refer to the application and with MIDlet (with uppercase MID)we’ll refer to the MIDlet class.

The midlet life cycle

In module one it was explained how a MIDlet can be executed into a mobile phone and in particular in our WTK device emulator environment. It was said that a MIDlet state was managed by a particular application called JAM (Java Application Manager). JAM is responsible for MIDlet download, installation and execution. What about if a phone call arrives while we’re executing a MIDlet? How can we manage the MIDlet state especially if it uses some exclusive resources (i.e. bluetooth connection)? If a call arrives there should be a special application, the JAM – installed on the device – which stops or suspends our MIDlet (for instance, the MIDLet will be resumed after the call). Obviously the JAM can’t know what the MIDlet has to do when it is suspended, stopped or resumed. This is a MIDlet specific responsibility. So, the solution is that discussed in the first module: a set of callback methods and a particular class. The class for applets is the Applet class, for midlets it’s the MIDlet class. This class, which we’ll see in detail in the next paragraph, has some utility methods but also – and most importantly – the callback methods we have to implement to manage MIDlet state change events.
We already know that the MIDP profile is based on CLDC configuration. It’s written in the CLDC specification that a CLDC application has a main(String[] args) method as entry point. This is not the case of a MIDlet, which is instantiated by the JAM in a optimized way (from the CPU and memory point of view). A MIDlet can be in one of the states in Tab_2.1.

We can now describe the MIDlet lifecycle using Fig. 2_1 and see what happens after deciding to execute our favorite MIDlet. After the user decides to execute the MIDlet, the JAM creates it invoking midlet default constructor. Obviously, our midlet will be described by a class which is an realization of MIDlet class as we’ll see later. So, our class must have a default constructor. If we create a constructor with parameters we have to remember to specify also the default constructor as java language rules tell us. If the default constructor execution fails, the JAM will notify the user with a proper message which is dependent by the particular device implementation. If the constructor executes without errors, the JAM puts the midlet into PAUSED state. In this state the MIDlet is instantiated but it hasn’t gained access, yet, to all the resources needed to start its execution. If all the resources are available, the JAM puts the midlet into ACTIVE state and notifies this invoking the startApp() method which has the following signature:

protected abstract void startApp() throws MIDletStateChangeException

Fig.2_1

Many interesting remarks may be said about this method. The first is that it’s an abstract method and so every MIDlet must implement it. As we said before, it must contain all the code about midlet resource initialization, which is error prone. For instance, some resources may not be available. So, the method can throw a MIDletStateChangeException which is the specific exception for midlet error change state management. Someone reading this topic may argue that the MIDlet we created in the first module didn’t have the throws clause. That’s because the method we created was an overriding and we know that we don’t have to declare all the exceptions the parent class method does. The important thing is that we haven’t to add exceptions not present in the parent class or RuntimeException which must not be declared in the throws clause. If we need to manage some errors here, we have to wrap the specific exception into a MIDletStateChangeException, which will be managed by the JAM environment. In that case the midlet will be put into DESTROYED state, and then it will exit.
The main thing on which to focus, now, is that the JAM will invoke our startApp() method every time the midlet is executed. So, in this method we have to put all our initialization code.
When the midlet is in the ACTIVE state it’s running and so it has all the resourses it needs. The JAM now may decide to put the midlet into PAUSED state again. It’s the case we described earlier; for instance: a phone call arrived. What happens then? The midlet changes its state, and this event must be notified invoking the following callback method:

protected abstract void pauseApp()


In this method the midlet must release all exclusive resources (the screen for instance) it owns passing to the PAUSED state. If, some time later, the JAM decides to return the midlet to the ACTIVE state it has to invoke the startApp() method again.
What about the midlet if we want to change its state? The midlet can’t change its state in a secure way but can ask the JAM to do that. If the midlet is in the ACTIVE state and we want to put it into PAUSED state we can call the method:

public final void notifyPaused()


This method tells the JAM that our midlet wants to be put into PAUSED state. On the contrary, if the midlet is in the PAUSED state and wants to become ACTIVE, we can call the method:

public final void resumeRequest()


It’s very important to remark that this method invocation doesn’t put the midlet into ACTIVE state but asks the JAM to do that. If the JAM grants the request, it has to invoke the startApp() method again to notify that.
Last but not least, the midlet may be in the DESTROYED state, in which the midlet is not running and releases all its resources. There are two ways to get into this state. The first is a JAM initiative. If the JAM decides to put the midlet in the DESTROYED state, it invokes the following MIDlet method:

protected abstract void destroyApp(boolean unconditional) throws MIDletStateChangeException


which has a parameter and can throw a MIDletStateChangeException. The parameter name explains itself. If the value passed by the JAM is true, and the method executes without exception, it means the midlet must be destroyed and so it will stop running. If, in this case, an exception is thrown, the midlet remains in the ACTIVE state. If the parameter’s value is false, it means the MIDlet method implementation may ask to wait a while before stopping the midlet. How can the midlet notify this? In order to ask the JAM not to stop the midlet, the destroyApp() implementation can throw a MIDletStateChangeException.

To pass in the DESTROYED state, the midlet can ask the JAM to do that calling the following MIDlet method:

public final void notifyDestroyed()


In this case it’s very important to remember that invoking this method puts the midlet into DESTROYED state, but doesn’t free all the resources. As we’ll see later, it’s a good practice to call, before notifyDestroyed(), the destroyApp() method whose task is to free resources.
We should remark that the callback methods are abstract and notification methods are final.
So, in the startApp() method we put resources initialization and in the destroyApp() method we put resources releasing.

About MIDlet class constructor

Midlet lifecycle is a very important concept in MIDP programming because it tells us how to implement callback method for JAM, and device interaction. Every MIDlet we’ll create will be a realization of the MIDlet class which describes callback and utility methods (Fig 2_1). So every specific midlet must define how to manage resource implementation, in the proper way (MIDlet abstract methods as we’ll see later). Before going on we remark that the MIDlet class constructor has a protected visibility modifier. This means that the only way to create a MIDlet instance is through a specific realization. About the MIDlet constructor we can also say that it will be executed once when the midlet is executed and it’s not executed when midlet is paused and resumed later. In the constructor we’ll put all the code about things the midlet needs, which are not exclusive or used by other applications. It’s the case of particular objects owned by the midlet as well as a specific Form or other widgets. As we said before, after the constructor execution, the midlet is in the PAUSED state.

Our first MIDlet review

Now we’re are able to understand better our first MIDlet in List2_1. We can see how the GUI is created inside the startApp() method and that we don’t have any particular resource allocation. We also notice that our midlet is described by the MyFirstMIDlet class which is a specific realization of MIDlet class with its abstract methods impemented.
The JAD file
In the first module we talked about the Java Application Descriptor (JAD) file, which is very important in the midlet deployment process. As we’ll see later in detail, this file contains a lot of configuration information about the midlet we want to deploy. Before going on, it’s very important to notice that we’re talking about a JAD for a midlet, but a JAD file is designed for a midlet suite which is a set of midlet applications contained inside a single jar file. Usually we have just one midlet inside a jar file, so we assume that a midlet suite corresponds to a midlet, but keep in mind that it’s not always the case.
Information inside a JAD file can be divided in:

- required or mandatory
- optional
- custom

In order to see how to manage these configuration data, we’ll use our WTK, selecting the settings option on the menu. If we select the required tab, the panel in Fig2_3 will be shown, listing JAD mandatory properties.


Fig.2_3

The first one is a property about jar size and it’s used by a security check mechanism. When the device reads the jad file and gets the corresponding jar file, it checks if the jar size is equal to the value set in the jad file. If this is not the case, the device may decide not to install the midlet suite. This information is also used by the device to check if it has the required space to store and execute the application. As we said before, the size is a mandatory information and is set by our tool, as shown in Fig.2_3. The second property is the name of the jar file the device will download. Obviously it must be equal to the file present on the download server. The third mandatory property is the name of the midlet suite. This is the name the device will prompt to the user when referring to the midlet application. We can write here what we want without restriction. This is also true for the vendor which is another useful information. More important is the version information of the application. This is an information that the device uses in case of midlet update. When the device tries to update the midlet suite, it checks the version number and asks the user if he or she wants to update the application, prompting the current version and the new one.

The last properties in the mandatory properties list regard the information about the configuration and the profile version the device must have to execute the midlet. If our midlet, for instance, uses floating point, it requires CLDC 1.1 and so we have to write this information in the JAD file. In this way devices which are not compatible with CLDC 1.1 cannot download the midlet suite. In our example we have a JAD file that describes a midlet which can be executed by every device compatible with MIDP 2.0 and CLDC 1.0 configuration.

Optional properties are the ones we obtain by selecting the Optional tab in the Settings panel (Fig.2_4). In a later module we’ll talk about Record Management System (RMS), which is the tool – provided by the MIDP – which manages persistent data. A midlet may or may not use persistent data. If a midlet needs to store data in a persistent way, and it knows the size of these data, it can declare it in the JAD file using the property MIDlet-Data-Size. When the device wants to download the midlet it can check if the minimum persistence store size required by the application is available. If the available memory isn’t enough, the device may decide not to execute the midlet or execute it only partially.


Fig. 2_4

The properties MIDlet-Delete-Confirm and MIDlet-Delete-Notify are useful when the midlet is installed via Over The Air (OTA). The first may contain the URL called by the device when the user asks the device to delete the midlet. The second contains the URL called by the device when the midlet is deleted. The device may or may not call the URL written here: the behavior is device dependent. The same applies for the property MIDlet-Install-Notify about the midlet installation process.

The other properties are about midlet suite description, allowing us to specify a textual description, an icon or an URL where the user can find more information as well as help about the application.
At last we discuss the custom properties we can put into the JAD file using the properties panel after pressing the User Defined tab (Fig. 2_5). Here we can insert our custom properties in the form of name/value pairs. Clearly it’s a good practice to use property names which are midlet contextual and so, in our example, we insert a property named it.actionscript.mobile.m02.MyFirstProject.custom with the value MobileValue. Before learning how to read this information from our midlet it’s very useful to take a look at the JAD file just created:

MIDlet-1: MyFirstProject, MyFirstProject.png, it.actionscript.mobile.m01.MyFirstMIDlet
MIDlet-Jar-Size: 1706
MIDlet-Jar-URL: MyFirstProject.jar
MIDlet-Name: MyFirstProject
MIDlet-Vendor: Unknown
MIDlet-Version: 1.0
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-2.0
it.actionscript.mobile.m02.MyFirstProject.custom: MobileValue

As we noticed earlier, there’s a single midlet in our midlet suite so we have just one MIDlet-<n> property. There should be a line like that for every midlet in the suite. Values – which are linked to the properties with the colon (:) symbol – in this case are the midlet name, the icon and the complete midlet class name. After that there’s the mandatory and the optional properties list. We notice how our custom property is put in the JAD file along with the others. The name we have choosen allows us to tell the property is used by our midlet (a useful information if there are many custom properties).
To read property values we can simply use this method:

public final String getAppProperty(String key)

exposed by the MIDlet class. To read our custom property value we can just write:

String value = getAppProperty(“it.actionscript.mobile.m02.custom”);

and get the value MobileValue. We’ll use this method in our timer application.

The platformRequest() method

Before creating our example midlet we’ll talk briefly about a method we inherit from the MIDlet class which can be very useful. Its signature is:

public final boolean platformRequest(String url) throws ConnectionNotFoundException

and it allows us to ask the device to call a service specifying a specific URL. The use of a specific URL is a way to delegate to the device the management of specific functions. If the device understands a given URL type, it can manage it. If not, it will throw a ConnectionNotFoundException. The type of urls tipically undestood by the devices are:
- web addresses the device accesses through the configured browser
- start a call if the url is of type tel://<number>

In the first case we can use this method to reference a jar or jad file. In this case the device may ask the user to download and install the corresponding midlet suite. In the second case the device can put the midlet into PAUSED state and start a call. When the call is finished it can resume the midlet to the ACTIVE state again, through the process described before. The thread management into which the new application is executed is device dependent.

The Timer

We finish our second module with a simple Timer midlet. In order to do that it’s a good idea to describe how the Timer class works in a MIDP environment. As we can see from the documentation – [1] – this class is contained in the java.util package along with the class TimerTask. A task is an operation we can do at a specific moment in time. The TimerTask describes the operation we have to do (the what) and the Timer is useful to decide when to do the task. What we have to do is to create an implementation of the abstract TimerTask class specifying its run() method and to register a task instance of the Timer.
In order to do that we have two options:

 fixed delay execution
 fixed rate execution

If we have more than one task, the first method must make sure that a task is executed after a fixed time after the preceding one is finished. If the duration of the task execution is longer that the delay, every task is executed sequentially. The second option allows us to execute the task at a fixed rate. For instance, in this way we can execute a task every 60 seconds. Clearly it’s a good practice to choose a delay or rate time which fits to the task the device has to execute. We notice how the Times is also suitable for executing a specific operation at a specific time. If the time is elapsed the operation will be executed presently. This is the feature we’ll use to create our simple midlet as a simple alarm clock. So, we’ll create the midlet AlarmClockMIDlet (List2_2) which is a simple MIDlet realization which reads a string from the JAD file that the midlet will show at a specific time set through a specific GUI. We won’t examine the GUI now, because it will be the subject of a future module, but we’ll see how to manage the Timer and TimerTask objects and how to read information from the JAD file. The code is commented, but it’s useful to remark some interesting things.

At first we can see how the timer is managed. We notice the creation of the timer instance in the midlet constructor because its lifetime is equal to the midlet one. In the constructor we also read the JAD property value associated to a property name which contains the string to show when the alarm is triggered. If the value is null we use a default value. We initialize then the date we’re going to edit with a DateField we create in the startApp() method. As we mentioned before, we’ll talk about GUI in a future module. In the startApp() method we also create all the GUI elements we’re going to use. Then, we create the Form containing the DateField and we manage commands about midlet exiting and alarm setting. Command management is in the commandAction() callback method described by the CommandListener interface the midlet implements. The exit command is managed as usual. In the setting command management block we read the date value from the DateInput widget, we create a TimerTask instance and we register it to the timer. We notice how it’s very simple to create a TimerTask instance in the anonymous way. In the run() method we just call the showAlertMessage() method we’ll talk about later. We notice that anonymous classes are allowed by the compiler’s specification, and so is not in conflict with the J2ME specification. We also notice that in an application like that, we need to create a new instance of a TimerTask every time. In fact we can’t register the same instance with the timer more than once. The simple method showAlertMessage() just shows an alert containing the message previously read. Last but not least is the destroyApp() method implementation which contains the release of the timer resources through the cancel() Timer method invocation. As seen before, this method is invoked when the JAM stops the midlet execution.

Conclusion

In this second module we studied an important concept in midlet programming: the midlet lifecycle. We learned how to create a simple MIDlet realization implementing callback methods in the proper way. We also studied how to create and to read some configuration information contained into the JAD file and we saw how to manage scheduled jobs in a MIDlet. In order to do that, we used a simple MIDlet but the same concepts apply in more complex applications. In the next module we’ll study the more important high level API for GUI creation and command management.

About the author

Massimo Carli (http://www.massimocarli.it/site) is a Java Architect working as Software Consultant in Italy. He has over 12 years of experience in Java and Internet application. One of the founders of Mokabyte (http://www.mokabyte.it), he has written more than 100 articles about Java, Perl and UML for italian magazines. Certified as J2ME programmer he has written a book about MIDP 2.0 (in italian) you can read on his web site.

References
[1] MIDP 2.0 API http://java.sun.com/javame/reference/apis/jsr118/

Related Download: AlarmClock.zip

Comments

comments

Leave a Reply

Your email address will not be published.


*