by Jonathan Knudsen
May 2003
Download:
[MIDlet suite JAD]
[MIDlet suite JAR]
[Source code ZIP]
Related Documentation:
User's Guide
API documentation
The Sun Commerce Animation Tutorial (Sun CAT) MIDlet is based on an
X Windows application called Neko, originally
written in Japan in 1990. It features an animated cat that chases a mouse around
the screen. This article describes some of the salient technical features of the
Sun CAT MIDlet and serves as a guide to the source code.
Introduction
Masayuki Koba's original xneko.c source code has been ported or reimplemented on
dozens of platforms. I first encountered Neko as a NeXTStep application some
time around 1992.
The Sun CAT MIDlet retains the behavior of the original application through
careful porting of the original C source code to Java. In addition, the Sun CAT
MIDlet can download alternate animation images, called
skins, from a server. The application uses HTTPS for data security to
allow skins to be purchased from the server when the user enters a credit card
number into the MIDlet client. Although the server does not actually make
charges on the credit card, the application demonstrates how it could be done.
The Sun CAT application is a full-featured showcase of several important
techniques in MIDP programming:
- Implementing animation in a modular way to ease porting between MIDP,
Personal Profile, and J2SE
- Using a worker thread to keep the user interface responsive
- Using HTTPS to protect sensitive application data
Understanding Sun CAT's Animation
I'll begin by describing how the cat itself is animated. From top to bottom,
midp.NekoMIDlet creates and displays a
midp.NekoCanvas, which uses a neko.Neko to implement
the cat's behavior. The
Neko object implements the core of the algorithm, ported from the
original C code. However, it is designed to be platform-independent and easily
portable to other Java stacks, like Personal Profile and Java 2 Platform, Standard
Edition. NekoCanvas handles the details of loading images and
displaying the current state of the Neko object. Finally,
NekoMIDlet provides the application framework for loading the
catalog and buying additional skins.
Neko keeps track of the position of the cat and mouse. You can
retrieve the cat's location using getX() and getY().
Similarly, the mouse's current location can be retrieved using
getMouseX() and getMouseY(). To move time forward by
one step, call tick(). Each time you call tick(), the
Neko updates its internal state, figuring out how the cat is moving
and what the current animation frame should be. The getImageIndex()
method returns an index describing the current frame that should be displayed
for the cat animation.
The NekoCanvas class uses a thread to call Neko's
tick() method once every 125 milliseconds. NekoCanvas
also handles displaying the current state of the Neko object. At
initialization time, it loads images into an array in a specific order. It uses
Neko's getImageIndex() to figure out which image to
display at any instant in time.
The Worker Thread
Sun CAT makes extensive use of a worker thread to maintain a responsive user
interface while performing work in the background. I've already written about
how network activity should be performed in a separate thread:
Sun CAT goes one step further by placing all persistent storage activity in the
worker thread. Access and manipulation of record stores can be slow,
so related activity should be performed in
a separate thread to avoid locking up the user interface.
The worker thread is implemented in util.Worker.
Worker maintains a list of tasks and executes them in sequence.
Each task is an implementation of util.WorkerTask. The code that
should be run in the work thread is in run().
WorkerTask's run() method differs from
java.lang.Runnable's run() method in that it can throw
an exception and has a return value of type Object.
The Sun CAT MIDlet (the midp.NekoMIDlet class)
implements the util.WorkerListener interface to be notified of
important events in the worker thread's life. For example, every time
Worker finishes executing a task, it calls the
WorkerListener's completed() method, passing both the
task object and whatever object was returned from the task's run()
method.
One last interface, WorkerProgress, rounds out Sun CAT's worker
thread API. WorkerProgress shows the progress of the worker thread
as it executes tasks. WorkerProgress can be implemented by wait
screens that are shown while the worker thread is executing tasks.
Sun CAT doesn't need a dedicated wait screen; it simply uses the main screen
with the cat animation. NekoCanvas implements the
util.WorkerProgress interface, which means it's capable of
indicating the progress of the worker thread. NekoCanvas features
an animated progress indicator and a text message that are drawn over the cat
animation to indicate background activity. The following screen shot shows
Sun CAT waiting for the catalog to load.
Sun CAT's progress display
|
Network Protocol
Sun CAT uses a compact protocol to communicate between client and server. There
are two possible interactions:
-
In the catalog interaction, the client requests a catalog of
available items from the server. The server returns metadata about items: name,
description, price, and a thumbnail image.
-
In the buy interaction, the client submits credit card information and
receives the bought items.
Complex data types are written and received using DataInputStream
and DataOutputStream. The following tables detail the exact types
that are exchanged for each interaction.
Catalog protocol
| Origin |
Type |
Description |
| client |
String |
Version string, in the form version/profiles, where version is
the Sun CAT client version and profiles is the system property
"microedition.profiles".
|
| client |
int |
The number of modules that are owned and stored locally.
|
| client |
int[] |
The ids of modules that are stored locally.
|
| server |
int |
The number of modules that follow.
|
| server |
byte[][] |
Serialized modules (thumbnails only).
|
|
Buy protocol
| Origin |
Type |
Description |
| client |
int |
Number of modules that will be purchased.
|
| client |
int[] |
The ids of the modules that will be purchased.
|
| client |
String |
Credit card number.
|
| client |
String |
Credit card expiration date (MMYY).
|
| client |
String |
Credit card security code.
|
| server |
int |
The number of modules that follow.
|
| server |
byte[][] |
Serialized modules.
|
|
If the credit card cannot be validated in the Buy protocol, the
server returns a length of 0, followed by a String that contains a
failure message.
Using HTTPS
None of the Sun CAT code changes if HTTP or HTTPS is used. All you have to do is
switch the URLs in the application descriptor. The Sun CAT-catalog-url and
Sun CAT-buy-url MIDlet properties control how the client connects to the server.
If they are HTTPS URLs, the client will use HTTPS (if it is available) to
connect to the server.
For more details on HTTPS in both MIDP 1.0 and MIDP 2.0, see
MIDP Application Security 2: Understanding
SSL and TLS.
Summary
The Sun CAT application is a full-featured end-to-end Java application. The
MIDlet client demonstrates animation in MIDP, using a worker thread for both
network and persistent storage activity, and desigining an efficient
client-server protocol. HTTPS can easily be used for secure purchases.
About the Author: Jonathan Knudsen
[e-mail]
[home page]
is the author of several books,
including
Wireless Java (second edition),
The Unofficial Guide to LEGO MINDSTORMS Robots,
Learning Java (second edition), and
Java 2D Graphics.
Jonathan has written
extensively about Java and Lego robots,
including articles for JavaWorld, EXE, NZZ Folio,
and the O'Reilly Network.
Jonathan
holds a degree in mechanical engineering from Princeton University.
Back To Top
|