Issues with MIDlet Programming
This report presents a series of issues confronted with when programming for Java cldc enabled devices. These are very limited java devices with about 500k heap space and a maximum MIDlet size of 128k. These were noted when programming specifically for the Motorola A835 phone device, but should apply for most MID1.0 enabled devices.
Jan Humble <jch@cs.nott.ac.uk>
General
Never rely on emulators alone, test thoroughly on the device itself.
No floating point arithmetic. Careful not to declare any 'double's or 'float's since they will pass pre-verification but will generate an application error on the phone, even if they are never called.
No trigonometric functions, but matrix operations for rendering can be faked ia byte shift operations on 'long's. Tricky and time consuming, subject to application specific tasks.
- Obfuscators may alter your code in unwanted ways, so test thoroughly after obfuscation on the emulator and device.
- Thread responsibly. You are not allowed unlimited amount of threads (6 at a time on the A835) so choose wisely and synchronize carefully. Do not rely on the emulator for thread sequencing, priority or lifetime. Thread lifetimes may differ considerably on the emulator compared to the device itself.
- Call the System.gc() garbage collection explicitly between memory intensive tasks.
Rendering
---------
- Only PNG format supported, however several JPEG and GIF decoders are available but take up MIDlet space and do not provide any substantial gains.
- Per-pixel computations
- Relatively large images take a substantial amount of space when expanded. Will easily overrun the buffer even at low bpps.
- Consider tiling with an optimum tile size of the screen viewport.
- Call System.gc() when cleaning image buffers. Works reasonably fast. Careful however on keeping image buffers (such as tiles) active in the background, since the limited resources will not allow you to override a buffer with a new one without overruning total memory. Clean before create might be a good tip.
- Clipping is your best tool. Use setClip() on every independently renderable object. Remember however that this only works with renders of primitive 'Graphics' calls. If you use your own matrix pixel buffer you will need to implement your clip constraints yourself.
- Vector graphics might be an option (such as the TinyLine package), but then authoring vector graphics might not be in your agenda or it might take too large a bite out of your midlet size.
Telephony
---------
- Can only be done via a TextField on a Form. However, one can always override the paint(Graphics g) on the the Form to create your own render context with a Form and TextField "hidden" underneath.
- Voice calls may hang, and not allow you to return to the MIDlet.
Networking
----------
- Some service providers will not allow socket connections over TCP, or not anything else for that matter. HTTP connections should be accessible through most apis on most devices.
- Connections are very unstable, do not expect prolonged uninterrupted service provisions. Do not expect first time connection success every time. Opt for a recovery, constant polling on network status, or better yet, a datagram scheme (if available) for reliable message delivery.
- Some service providers do not allow concurrent voice and data connections. Voice/Video calls might not be able to interrupt midlet created data connections. You might need to close all data connections before allowing a voice or video call. However the API close connection methods might not drop connections substantially without actually killing the midlet :-(
- One should never rely on network emulation, specially with process intensive background tasks. MIDlets tend to block on connection failures, and block background rendering procedures. Thread all connection handlers carefully.
- design with the mininum message size possible in mind. Not only for reliablity and speed but service providers charging on a per kb basis.
Storage
-------
- Remember to create a RecordStore even if only attempting to read from an non-existent one. It might throw an application error.
- Don't rely on sequential record ids as a reference for record addresses. Use a RecordEnumeration and store with e g a prefix (say "Name:" + value) and search for that prefix for the value accross all records. If single entities need to be stored then perhaps separate record store files might be considered.
- Don't rely on the first record id to be '0'. Some platforms or emulators start record numbering at '1'.
Deployment
----------
- A good way to deploy to different platforms and/or specify different application parameters is to set the values on the JAD file and call the getAppProperty() from your MIDlet class.
- Use an 'ant' extension such as 'antenna' to easily generate JAD files, obfuscate, generate JADs, manifests, etc for midlets.
- Use different JAD files for different deployments. E g You might want to use a different JAD file for testing on the emulator than an OTA (over the air) deployment scheme specifying the MIDlet-jar-url.
- Use enable version updates on your JADs, this will allow for users to download over the original midlet installation without the need of erasing the old one. Try only to update versions on actual deployment releases and not on every compile. This is another reason why to use different JADs for different purposes.
Motorola A835 specific issues
-----------------------------
- Java only api CLDC 1.0, MIDP1.0, Gaming API. Need to use the GamingApi GameScreen in order to play sound files.
- Only WAV, MIDI supported and only specifc wav parameters.
- System property keys are defined but most values are not set. Not very useful.
- Motorola motocoder emulator not very good.
* Image buffer broken, large images will not render in their entirety.
* RecordManager does not work.
* socket support disabled, but enabled on device
* Midi and wav files might play in emulator but not in phone and viceversa, check file formats.
* Emulator crashes on unhandled exceptions, however device seems more robust.
* Emulator throws thread exceptions when they shouldn't be there, specially on threads containing openConnection() code.
- Only one font and one font size provided.
- No api for voice (other than initiating a call), video, storage (other than MIDlet records) or anything else useful for a mobile phone.
|