Java Solutions


Writing Java Applications for Mobile Devices

Michael J. Yuan

J2ME: Making good on the Write Once Run Anywhere promise. Here's how to make it happen in the Palm world.


Java in a Wireless World

One of Java’s greatest promises is the ability to build platform-independent applications. Java applications are byte-code programs running inside VMs (virtual machines). VMs can be ported to many operating systems (OSs) and allow Java byte code to run independent of the hosting OS. However, the cross-platform compatibility of Java has been embraced with limited success in the world of desktop computing. Desktop computers are dominated by one platform: Windows. The performance penalty of running non-native byte code on Windows discourages developers from using Java in single-platform applications.

However, in the world of handheld devices, Java’s ability to “write once, run anywhere” might give Java the ultimate chance for success. As wireless hardware quickly improves, you will soon see standard cell phones running sophisticated client-side programs on various hardware/OS platforms. It is crucial for wireless application developers to use a language that can work with various device platforms on the market. Java’s promise of platform independence meets such a demand.

Using Java to develop mobile applications has other advantages: Java is a well designed object-oriented language that supports advanced programming techniques; Java VMs can safeguard memory leaks, which are especially dangerous for small memory devices; Java-based mobile applications can integrate seamlessly with the large number of Java server-side applications existing on the Internet.

In this article, I will discuss how to use the Java platform to develop mobile applications using Palm application development as my example.

MIDP

J2SE (Java 2, Standard Edition) is designed for desktop computers. Since handheld devices have much less processing power and memory than desktop computers, it would be unwise to port the whole J2SE environment to the wireless world. Instead, you need a small footprint, fast Java run-time environment with a limited set of the most useful functionalities for mobile applications.

To enable Java development for wireless devices, Sun released a stripped down version of Java called J2ME (Java 2, Micro Edition). J2ME is divided into configurations and profiles. You can use different combinations for different processing power and memory requirements. The CLDC (Connected Limited Device Configuration) and MIDP (Mobile Information Device Profile) combination is designed for resource-constrained mobile devices, such as cell phones and low-end PDAs. CLDC provides class libraries to support a limited set of Java core language APIs; MIDP provides device-specific implementations for application-level APIs, such as GUI components, network connection, and persistent storage. CLDC and MIDP work together to provide a complete development and run-time environment for mobile devices. In this article, I will refer the CLDC/MIDP combination as MIDP. To create MIDP applications, you need implementations of CLDC and MIDP, which can be downloaded from Sun’s website (<http://java.sun.com/products/cldc/> for CLDC and <http://java.sun.com/products/midp/> for MIDP).

MIDP applications run on any cell phone or PDA device that has an MIDP VM installed. A particularly important platform for MIDP is the Palm devices. In this article, I will use an MIDP environment for Palm devices to illustrate how to develop MIDP applications.

Example

An MIDP application usually consists of one or several related MIDlets and their supporting classes. A MIDlet is a Java class extending javax.microedition.midlet.MIDlet. The example application consists of two MIDlets (see Figure 1). The MIDlet FetchPage allows a user to enter an Internet URL in a text field (see Figure 2). After the user hits the FETCH button, FetchPage makes an HTTP connection to that URL and displays the content it fetched in a text box (see Figure 3). If the URL is not valid, FetchPage returns an error message (see Figure 4). The MIDlet FetchPage stores all the valid URLs it visited in an on-device database, which can persist through soft resets. The MIDlet History allows you to read the stored list of visited URLs (see Figure 5). The source code for this application can be downloaded from <www.cuj.com/code>.

The implementation of this example covers major topics of MIDP programming, including high-level GUI components and event handling, network connectivity, and persistent storage. In the next two sections, I will discuss the above topics in detail. The only topic that I leave out in this example is low-level GUI programming. If your main interest is using MIDP to develop wireless games, you can refer to [3] for topics on low-level GUI programming.

MIDP GUI Programming

In a nutshell, a high-level GUI MIDlet has the following components:

  1. A Display: Before the MIDlet can display anything on the PDA screen, it has to get a Display object through static method javax.microedition.lcdui. Display.getDisplay. Display is associated with the hardware LCD.
  2. One or more Screens: a MIDlet can have one Display object and several Screen objects. Display can make any one of the Screen objects visible at a given time by calling the Display.setCurrent method. There are four types of Screen objects: Alert, TextBox, List, and Form. Among them, Form is the most flexible since you can add other smaller GUI components in a Form. Those smaller components include ChoiceGroup, DateField, Gauge, StringItem, TextField, and ImageItem.
  3. Command buttons: a Screen contains multiple Command objects, which appear like buttons on the display. When the user presses a Command button, it generates an event that can be captured by the CommandListener object of the current Screen. Command is the only way to navigate among Screens and invoke GUI event-processing methods.
  4. A CommandListener for each Screen: a CommandListener is associated with a Screen through the Screen.setCommandListener method. CommandListener analyzes the events from Command buttons and performs appropriate actions through its commandAction method. In my example, the CommandListener of Screens in a MIDlet is set to be the MIDlet itself for simplicity.

Skeleton code for the example MIDlet FetchPage is shown in Listing 1.

Network Connectivity and Persistent Storage

An MIDP application can access remote and local data through HTTP network connections and local persistent data storage.

HTTP network connections: mobile Internet applications need to deal with data anywhere on the Internet. Therefore, the ability to establish network connections and read/write data streams through these connections is very important. Interface HttpConnection defines basic HTTP functions MIDP can perform. You can create an HttpConnection object by passing a valid HTTP URL as a string parameter to static method javax.microedition.io.Connector.open. Methods openDataInputStream and openDataOutputStream in an HttpConnection object return the input and output streams from the current connection. You can then send data to the HTTP server at the other end of the connection by writing into the output stream and retrieve data from the server by reading from the input stream. Listing 2 illustrates the use of HTTP connections in the MIDlet FetchPage.

Local data storage: in addition to remote data, applications also need to store and access data locally. Local data access is fast and reliable. In the case of mobile applications, locally stored data allows the program to function continuously even when the network connection is temporarily lost. In the MIDP specification, the RMS (Record Management System) is designed to store data in on-device memory. A RMS record store acts like a file in the file system. It can be accessed by its name through static method javax.microedition.rms.RecordStore.openRecordStore. Since a record store is accessed by its name rather than its reference, the same store can be accessed from different MIDlets. RMS record stores can survive power off and soft resets. Data in a RMS store is organized in a series of records. You can add a new record to a store using the addRecord method, and it returns a serial number that is automatically assigned to the new record. A record can be accessed by its serial number through the record store’s getRecord method. If you do not know the serial number of your target record, you can iterate through all records using a RecordEnumeration object returned by the RecordStore.enumerateRecords method. Listing 3 shows skeleton code for the RMS store management in the MIDlets FetchPage and History.

Steps to Create an MIDP Application

Since MIDP applications are Java byte-code applications, you need an MIDP VM on the target platform to interpret and run the byte code. The target platform in this example is the Palm OS. The MIDP 1.0 VM for Palm devices can be downloaded from Sun’s website (packaged in the MIDP4Palm development kit) at <http://java.sun.com/products/midp4palm>. To install it, you just need to synchronize the VM executable MIDP.prc into your Palm device. To run the example code correctly, you need to enable networking in the Preferences section. The Palm MIDP VM itself is around 600 KB. The development kit also includes a conversion tool to convert Java classes into a Palm executable.

If you do not have a network-enabled Palm device, you can still develop network MIDP applications using an emulator. A Palm OS emulator can emulate all combinations of Palm hardware and OS versions on your desktop computer. The emulator software is available for Windows, MacOS, and Unix/Linux platforms. You can download it from Palm Developers website (<www.palmos.com/dev/tools/emulator/>). To run network applications, make sure you select “Settings/Preferences/Redirect NetLib calls to Host TCP/IP” on the emulator.

The following steps are required to create an MIDP application:

  1. Use the J2SE byte-code compiler to compile the source code files into class files. Use the CLDC/MIDP classpath as the compiler’s -bootclasspath and -classpath.
  2. Use the Preverify tool packaged inside the CLDC development kit to pre-verify the compiled classes into directory output. Pre-verification makes the MIDP VM light weight and fast. Use the same -classpath as in Step 1.
  3. Pack the pre-verified classes’ output/*.class into a jar file. To convert the jar file into an executable MIDP application, you need to specify meta information such as the MIDP VM version, the MIDlet names, and the corresponding class for each MIDlet. The meta information is specified in the Jar manifest file. The manifest file I used in the example application is shown in Listing 4. The manifest file can be specified using the jar command’s m option.
  4. Use the class com.sun.midp.palm.database.MakeMIDPApp in Converter.jar, which is distributed with the MIDP4Palm package, to convert the jar file in Step 3 into a Palm .prc application.
  5. Upload the .prc application created in Step 4 onto the Palm device.

Now, when you click on the icon of the new MIDP application on your Palm PDA, it will automatically invoke the MIDP VM and start execution.

Integrate MIDP with J2EE Using XML

My example application shows that it is quite easy to write a simple GUI-based network application using MIDP. But fetching and displaying raw HTML code is not very useful in the real world. To harness the full potential of a J2ME mobile application, you need not only to connect with Internet back-end services, but also to understand and manipulate the content. This requires the MIDP application to speak the same language as the back-end application servers. That language is XML.

XML has become the standard communication language between application servers because it is very robust. XML functionality is the most important feature you need in order to integrate MIDP applications with web service back-ends. The current MIDP specification does not have XML processing requirements. So, for now, you have to rely on third-party tools. Although there are a lot of Java-based XML tools available, most of them cannot be used in MIDP applications because they require string and I/O functions beyond the CLDC core APIs. You need a light-weight, robust XML processing tool for MIDP applications. One of the best CLDC-compatible XML parsers is the open source kXML developed by Enhydra. The kXML parser supports both stream-based and tree-based XML parsing. To learn more about kXML, visit its website (<http://kxml.enhydra.org/>). For more information about integrating MIDP applications with J2EE servers, see [1].

The Future of MIDP

As discussed above, the lack of XML capabilities in the current MIDP 1.0 specification has impeded the ability to create a MIDP front end for enterprise database and application servers. In addition, secure connectivity is not built into the current MIDP standard either. The lack of a secure communication channel limits MIDP’s application in mobile commerce. On the user-interface front, the limited MIDP GUI design makes it difficult to create multimedia or game applications.

The next generation MIDP standard, MIDP 2.0, currently under Java Community Process (<http://jcp.org/jsr/detail/118.jsp>), addresses the above concerns while remaining compatible with MIDP 1.0. New features proposed in MIDP 2.0 include:

  1. A security model including code signing and verification.
  2. Secure networking including HTTPS.
  3. A built-in lightweight XML parser.
  4. A more flexible low-level GUI control.
  5. PUSH architecture.
  6. A sound API.

Beyond MIDP

MIDP strives to be a device-independent Java mobile application platform. However, in order to run on the smallest mobile devices, MIDP must have a conservative set of features. Today’s PDAs have hardware capabilities much greater than mobile phones, which MIDP was originally designed for. If your target devices are low-end PDAs (such as Palm devices), you may consider using other Java development tools to take advantage of their power.

J2ME PDA Profile (<http://jcp.org/jsr/detail/75.jsp>) is an upcoming J2ME profile based on CLDC. It is designed for PDA devices, which are generally more powerful than MIDP devices. However, at the time of this writing, its specification has not been finalized.

kAWT (<www.kawt.de/>) is an AWT port for J2ME KVM. It relies only on the core API functions provided by CLDC. It allows desktop Java GUI programs implemented using AWT to be ported to PDA platforms with little modification. kAWT also supports color LCD devices. Compared with MIDP, kAWT offers much better functionality in GUI programming and provides better support for new hardware.

If your target platforms are high-end PDAs such as iPAQ and Zaurus, there are more powerful Java environments. Jeode (<www.insignia.com/products/default.asp>), developed by Insignia Solutions, offers Emdedded Java- and PersonalJava-compatible VMs and core API classes. Jeode has almost the full power of J2SE. You can run multi-tier networked Java applications directly from Jeode powered devices.

Conclusion

In this article, I have reviewed popular Java technologies for writing portable programs on mobile devices. In particular, I have discussed J2ME/MIDP technology and given an example on how to create GUI-based network programs for Palm devices.

Notes and Resources

[1] Michael Yuan and Ju Long. “Build Database-Powered Mobile Applications on the Java Platform,” JavaWorld, January 2002, <www.javaworld.com/javaworld/jw-01-2002/jw-0118-midp.html>.

[2] Sun’s SmartTicket J2ME/J2EE showcase demonstrates the power of enterprise J2ME applications, <http://java.sun.com/blueprints/code/jsm10/application.html>.

[3] Two good J2ME/MIDP books are Learning Wireless Java by Qusay Mahmoud (O’Reilly & Associates, 2001) and Wireless Java Programming with J2ME by Yu Feng and Jun Zhu (Sams, 2001).

Michael J. Yuan is a PhD candidate at the University of Texas at Austin. He is interested in utilizing advanced computer technology to help scientific research.