4. Core APIs

THIS is the least exciting chapter of this book, but you should read it anyhow. Remember that great achievements are made up of many smaller achievements. To raise a child, you must learn how to change dirty diapers. To build a Great Pyramid, you must move a lot of rocks.

To kick butt with your MIDP applications, you have to understand the core APIs, which are similar but not the same as the corresponding APIs in the desktop Java platform.

  • Fundamental classes in java.lang define strings, primitive type wrappers, and important classes like Object and Thread.

  • The stream classes in java.io allow you to send and receive information. Stream classes are used mainly for networking and file access.

  • The utilities in java.util include basic collections, classes for handling dates and times, and a random number generator.

Don’t assume that you know all this stuff, even if you’re experienced with Java technology on the desktop or in a server environment. The constraints of small devices dictate that these APIs are more compact and less rich than their desktop counterparts.


Note

Image

For all you geezers that can remember JDK 1.0 (circa 1996), the core APIs for MIDP/CLDC are very similar to the corresponding JDK 1.0 APIs. Nevertheless, they are not identical. Read on to find out exactly what you can and cannot do with the core APIs.



Note

Image

MIDP, CLDC, and other mobile device Java technologies are grouped together as the Java Platform, Micro Edition (Java ME). Desktop Java technology is the Java Platform, Standard Edition (Java SE).


4.1. JVM Features You Might Miss

MIDP is based on Connected, Limited Device Configuration (CLDC), which is both a virtual machine specification and a set of core APIs. The virtual machine used in CLDC devices is more compact and has fewer features than its desktop cousin.

For reasons that are shrouded in the mists of legend, the CLDC virtual machine is known as the K Virtual Machine, or KVM. Some say the K refers to the kilobyte scale of CLDC devices, while others contend that K is short for Kaui, a project code name from the early days of MIDP.

Regardless of naming, KVM is missing some features compared to the Java SE platform:

  • No native methods. The Java SE platform provides a way for Java applications to invoke native code. CLDC does not include any such mechanism.

  • No object finalizers. When an object is harvested by the garbage collector in the Java SE platform, its finalize() method is called. In CLDC, Object has no finalize() method.

  • No reflection. The Java SE platform allows applications to examine classes and invoke methods dynamically. CLDC does not include this feature.

  • No classloaders. This is more of a relief than a hindrance. The CLDC implementation has a classloader, of course, but it’s not accessible to applications. You cannot define other classloaders in your application.

  • Partial bytecode verifier. As discussed in Chapter 2, class files are preverified at build time. A second stage of verification is run when classes are loaded on the device.

4.2. Strings, Primitive Types, and System Methods

java.lang.String represents character strings, just as in the Java SE platform. The MIDP/CLDC String does not have all the bells and whistles that are in the Java SE platform, but in other respects it behaves just as you would expect. For example, the MIDP/CLDC String does not have methods relating to Locales, CharSequences, or regular expressions.

Memory is often scarce in a MIDP/CLDC device, so you should be careful about string handling in your application. The MSA specification requires a 1MB heap, which is generous, but it’s not the same unlimited feeling you get on the desktop. That heap memory might be shared with other running applications. Furthermore, if you rapidly create and discard many objects, the garbage collector might affect the performance of your application.

Although it’s convenient to assemble strings using the + operator, it is not the most efficient method. Consider using a StringBuffer instead, which creates a new String object only when you call toString().

MSA incorporates CLDC 1.1, which has all the same primitive types you’ll find in Java SE. If you want to write applications on older CLDC 1.0 devices, you’ll have to do without float and double. That’s all I’m going to say on that subject, because this book is about MSA.

Just as in the Java SE platform, class wrappers for primitive types are present in the java.lang package. For example, java.lang.Long is a wrapper class for the primitive type long.

Finally, java.lang.System and java.lang.Runtime include methods that apply to the whole system. You can find out the total heap size, the free heap memory, and the current time. You can run the garbage collector manually. The method you are more likely to use is System.getProperty(), which retrieves the value of a system property.

4.3. Threads

In most respects, threads work just as they do in the Java SE platform. To do some work in another thread, create a Thread object and call start(). Your old friend Runnable is still around too. Not surprisingly, the java.util.concurrent package is not available.

Like memory, however, processing power can be scarce on a MIDP/CLDC device. Threads, in particular, can be a scarce commodity. The MSA specification requires that an application must be allowed to create ten threads. Just because you can doesn’t mean you should. In general, try to use the fewest resources possible so that your application will run as smoothly as possible.

Many of the methods you will write in your applications are callbacks, which means that the thread is owned by the system, not your application. For example, when the device calls your MIDlet’s startApp() method, the thread that executes startApp() is a system thread. The rule about system threads and callback methods is to be clean and brief. It’s a lot like using a toaster in a cafeteria. You shouldn’t melt cheese into the heating elements, and you shouldn’t take all day because other people want to toast their bagels too.

If you must perform lengthy processing in response to a user action, put it in a separate application thread. Network connections definitely fall into this category, but plenty of other operations are slow enough to merit their own threads. Mobile devices are much less powerful than desktop computers, so even operations that seem to run quickly on a desktop emulator might be relatively slow on a real device.

4.4. Using Streams for Input and Output

In MIDP/CLDC, streams are defined in java.io, just as in the Java SE platform. To save space, the palette of streams in MIDP/CLDC is reduced to essentials. In particular, MIDP/CLDC does not contain more elaborate or exotic streams like PushbackReader, PipedWriter, and LineNumberOutputStream.

Despite the abbreviated java.io package, streams are fundamental to any type of input or output in MIDP/CLDC applications. Streams are used for reading and writing data over HTTP, IP, Bluetooth, and other types of network connections. Streams are used to exchange data with local file systems when they are available. Streams are crucial to the Generic Connection Framework, which is fully described in Chapter 18.

When working with InputStream or any of its subclasses, be wary of the available() method. Many programmers assume that it returns the number of bytes remaining in a file or network transmission, but in truth it returns the number of bytes that can be read without blocking. Most of the time, you have no use for this number.

Another common error with InputStream is assuming that the read() method will fully populate an array that is passed to it as long as there is enough data left in the stream. In reality, the implementation can read as much or as little data as it pleases. Always check the return value of read() to see how many bytes were actually pulled from the stream.

4.4.1. Be Clean

A final word of caution is to make sure you clean up after yourself. Like memory and threads, streams can also be a scarce resource on mobile devices, especially if they are related to network connections. Whatever streams you’ve opened, make sure you close them. Use finally to make sure streams get closed. This isn’t good enough:

Image

If any kind of exception is thrown while you are reading data, in will never be closed because your application will jump into the exception handler. A more robust solution follows. It’s more trouble, but it’ll work better and save you some heartburn.

Image

You can make it a little less messy by bumping exception handling up to the containing method.

4.4.2. Reading Input Data Completely

One common problem in MIDP/CLDC applications is reading all the data from a stream when you don’t know how much there will be. This often happens when you are retrieving data from a network connection.

A simple approach would be to allocate a big array and read directly into it. However, because memory is scarce, it makes more sense to allocate smaller chunks of memory as necessary.

Here is a method that reads all available data from an InputStream and returns the result as a properly sized byte array:

Image

4.5. Dates, Collections, and Random Numbers

As in the Java SE platform, java.util contains an assortment of useful utility classes. However, the toolbox is a lot smaller in MIDP/CLDC.

Dates are represented by java.util.Date, which is really just a thin wrapper for a long value representing the number of milliseconds since January 1, 1970. The long value is a standard way of representing instants in time and is exactly the same as in the Java SE platform.

A long or Date identifies a moment in time in a way that makes sense to a machine, but humans understand calendars and times specific to a time zone. The Calendar and TimeZone classes make it possible to convert between Dates and calendar fields that make sense to humans. In general, these classes are very similar to the Java SE platform, but a lot of the extra API weight (and convenience) has been shed in the interests of compactness.

Before you get too embroiled in Calendar, think about the needs of your application. If you just want to show a representation of a Date on the screen, or allow a user to enter a Date somehow, read about the DateField class in Chapter 8, “More User Interface.” It might be just what you need.

The java.util package also contains rudimentary collections, although they are a pale shadow of the Collections API that is part of the Java SE platform. MIDP/ CLDC includes Vector and Stack for keeping lists of objects and HashTable for mapping keys to objects. The Enumeration interface completes the party as a way to iterate through lists.

None of the collections are multithread safe. If you plan on accessing a collection from more than one thread, you must take steps to avoid trouble.

Finally, java.util.Random is a simple pseudorandom number generator. Create a Random and call one of its next methods to retrieve a pseudorandom number.

4.6. Summary

In this chapter, you learned about the core APIs of MIDP/CLDC. Classes in java.lang, java.io, and java.util provide stream handling, object collections, and other important functionality. These APIs are similar to the Java SE platform, but they are reduced in size and complexity to fit neatly on small devices.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.239.41