J2ME Bootcamp Sue Spielman President/Senior Consulting Engineer

J2ME Bootcamp
Sue Spielman
[email protected]
President/Senior Consulting Engineer
 2004 Switchback Software LLC
Who is Sue?
President of Switchback Software LLC
18+ years hands-on enterprise and mobile application
development experience
Author, technology columnist, magazine contributor, JSP
2.1 EG member
www.switchbacksoftware.com
© 2004
Objective
Provide a J2ME overview so that when you leave here
you’ll be able to get started doing J2ME
development.
www.switchbacksoftware.com
© 2004
Content
J2ME overview and the mobile landscape
Configurations and Profiles
How development is done with J2ME
Build Environment
MIDlet Development
Building a UI
Event Management
Networking
Working with Threads
Using a Record Store
Enterprise J2ME
kXML-RPC Usage
Couple of advanced topics…if we have time.
www.switchbacksoftware.com
© 2004
J2ME Overview and the
Mobile Landscape
www.switchbacksoftware.com
© 2004
Java Technology Editions
Java 2 Platform, Enterprise Edition (J2EE)
Enterprise solutions: ecommerce, ebusiness
Java 2 Platform, Standard Edition (J2SE)
Desktop solutions: standalone apps, applets
Java 2 Platform, Micro Edition (J2ME)
Consumer solutions: cell phones, PDAs, TV, STBs, cars
All based on the Java programming language
Different JVMs and APIs
www.switchbacksoftware.com
© 2004
Java 2 Micro Edition
Java 2 platform targeted at embedded and
consumer electronics
embedded systems, cell phones, pagers, PDAs, TV,
STBs
Consists of a VM and API’s tailored for such
environments
Modular architecture
Configurations
Profiles
Vendors have their own SDK’s on top of J2ME
with optional packages (Motorola, Nokia,…)
www.switchbacksoftware.com
© 2004
I’d Like to Buy a Vowel…
CDC – Connected Device Configuration
CLDC – Connected Limited Device Configuration
MIDP – Mobile Information Device Profile
MIDlet – Mobile app based on MIDP
AMS – Application Management System
LBS – Location Based Services
OTA – Over The Air
KVM – Kilobyte Virtual Machine
WTK – Sun’s Wireless Toolkit
WICS –Wireless Is Cool Stuff! (ok, I made this one
up…)
www.switchbacksoftware.com
© 2004
Java Micro Platforms
Device
Version
PC
PDA and Communicators
Phones and Pagers
Embedded Devices
SmartCards
J2SE
J2ME/CDC
J2ME/CLDC
J2ME/CLDC
JavaCard
www.switchbacksoftware.com
© 2004
Pretty much any type of mobile app you can
think of!
Client-only, CRM, ERP, Field data services,
POS, LBS/GPS, P2P Messaging, PIM,
Multi-media, Sales Force Automation,
Information services…you get the picture
www.switchbacksoftware.com
© 2004
Configurations and Profiles
www.switchbacksoftware.com
© 2004
J2ME Components
Optional Packages:
PDA (File and PIM), Mobile
Media, Wireless Messaging,
Mobile 3D, Location,
Bluetooth, Web Services
Optional Packages: RMI, JDBC
and Advanced Graphics (Swing
an Java 2D)
Personal Profile
Personal Basis
Game Profile
MIDP
Foundation Profile
CLDC
CDC
Java2 VM
KVM
OS
JavaOS or VMs
on top of BREW
or .NET
Device Hardware
Pagers
PDA’s
www.switchbacksoftware.com
© 2004
Internet
Appliances
Layout Source: Enterprise J2ME, Yuan. PH 2003
Configurations
Specific to a family of devices
i.e Common features of a device: CPU, RAM,
ROM, etc.
Comprised of
Virtual Machine
Core libraries
Classes, APIs
2 Configurations
Connected Device Config (CDC)
Connected Limited Device Config (CLDC)
www.switchbacksoftware.com
© 2004
CDC
Next generation devices:
Smart communicators, two-way pagers, home
appliances, auto systems, interactive TV-set top boxes
32 bit CPU’s
Min 512KB ROM, 256KB RAM (usually greater
than 2 MB memory)
Fully featured Java 2 VM and can use J2SE
libraries
Foundation Profile
Based on J2SE 1.3
www.switchbacksoftware.com
© 2004
CLDC
Designed for devices with resource constraints:
Cell phones, PDA’s, pagers, mobile POS
Target Device:
16 bit/16 MHz or higher CPU
160 - 512 KB memory (192KB min in CLDC 1.1)
Limited power, often battery powered
Limited bandwidth connectivity (<9.6Kbps)
Uses KVM
www.switchbacksoftware.com
© 2004
KVM
Sun's Kilobyte virtual machine
~ 50K
With libraries + KVM ~130K
Designed from ground up to meet needs to mobile
devices
Highly configurable but limits us because of size
restrictions
www.switchbacksoftware.com
© 2004
KVM Limitations
Doesn’t support float or double data types (CLDC 1.1
does)
java.util greatly reduced
Limited string, and I/O functionality
No JNI or custom class loaders
java.lang subset and in some cases modified interface and
implementation signatures
Runtime - Reduced signature to memory operations freeMemory(), gc(), totalMemory()) and exit()
System (reduced signature)
Threading – limited number of Threads, no thread pooling
File System replaced with RMS
Unicode is supported, but far fewer encodings are
supported
www.switchbacksoftware.com
© 2004
What You’re Basically Working With…
java.lang
Boolean
Short
Byte
String
Character
StringBuffer
Class
System (limited)
Integer
Thread (limited)
Long
Throwable
Math (Very different signature)
Runnable
Runtime (limited)
java.util
Enumeration
Data
Hashtable
Random
Stack
Timer
TimerTask
TimeZone
Vector
Date
Calendar
DateField (~DateFormat)
TimeZone
www.switchbacksoftware.com
© 2004
java.io
InputStream
InputStreamReader
DataInput
DataOutput
ByteArrayInputStream
ByteArrayOutputStream
OutputStream
OutputStreamWriter
PrintStream
Reader
Writer
Profiles
Defined through JCP (what isn’t?)
Sits on top of, and specifies a configuration
Specific to meet need of an industry or class of
devices
Specifies classes and methods needed for a
complete runtime environment
www.switchbacksoftware.com
© 2004
MIDP
Mobile Information Device Profile
Targeted at medium- to low-end cell phones and twoway pagers
Spec addresses issues such as
Application life cycle
User interface
Persistent storage
Networking
If you really have trouble sleeping…you can read
through the MIDP 2.0 spec @
http://jcp.org/jsr/detail/118.jsp
www.switchbacksoftware.com
© 2004
MIDP 2.0 is the latest version of the spec with lots of
cool new features. MIDP 1.0 is still around and is
still the predominate version supported on
devices.
www.switchbacksoftware.com
© 2004
MIDP 2.0
JSR-118 (a subset of Mobile Media JSR-135)
Formally includes OTA
Enhancements to enable reliable delivery of
services
Notifications enabled for success of install or
deletion of a MIDlet
Sockets
UDP Datagrams, Secure Sockets
Options, info, dynamic port addresses
www.switchbacksoftware.com
© 2004
MIDP 2.0 Secure Sockets
HTTPS – HTTP over SSL
SSL is a socket protocol that encrypts data sent
over the network and provides authentication for
the socket endpoints
Also includes javax.microedition.io.SecurityInfo,
which contains information about a secure
connection
javax.microedition.pki.Certificate, which represents
a cryptographic certificate
www.switchbacksoftware.com
© 2004
MIDP 2.0 - MMAPI
Subset of Mobile Media API (MMAPI)
http://jcp.org/en/jsr/detail?id=135
Enhanced UI
Custom Item support
Layout control
Graphical enhancements (like transparency)
2D Game API
Sound
Rich audio tone generation
Sampled sounds
www.switchbacksoftware.com
© 2004
MIDP 2.0 - Security
Protection Domains – for MIDlet and MIDlet suites
Recognizes the concepts of trusted and untrusted
code and permissions.
Untrusted code cannot make connections at will; it
must receive permission from the user.
Can indicate required and optional permissions in a
MIDlet suite using MIDlet-Permissions and MIDletPermissions-Opt descriptor attributes
Code can be designated as trusted if the
developer digitally signs it and the user's device
can verify the signature.
www.switchbacksoftware.com
© 2004
MIDP 2.0
A push registry that allows MIDlets to be launched
in response to incoming network connections
For example, maybe have a server socket listening on
the device for an SMS message that can then activate a
MIDlet
www.switchbacksoftware.com
© 2004
How J2ME Development is
Done
www.switchbacksoftware.com
© 2004
J2ME Steps
Slightly different than J2SE
1.
2.
3.
4.
5.
6.
7.
Code
Compile
Preverify
Create JAD & Manifest File
Package
Deploy (maybe)
Emulate/Run
www.switchbacksoftware.com
© 2004
www.switchbacksoftware.com
© 2004
Getting Started
Start with JDK 1.4.2 (or at least 1.3) to get the
platform, compiler, and other tools the WTK uses.
Download and install the WTK 2.1 from
http://java.sun.com/products/j2mewtoolkit/
Create a project, code, build, run
WTK will take care of javac –bootclasspath and
preverify for you…or you can write your own Ant
build.xml to do everything.
www.switchbacksoftware.com
© 2004
Dev environments: IDE’s
Can pretty much use whatever IDE you want.
Some are better than others.
Limited set of good tools at this point, but
improving
High End – costs $$
Borland’s JBuilder Mobile Edition
http://www.borland.com/jbuilder
Metrowerks CodeWarrior http://www.metrowerks.com
IBM WebSphere Studio Device Developer 5.6
Free
Sun’s Wireless Toolkit (WTK) 2.1
http://java.sun.com/products/j2mewtoolkit/
Eclipse http://www.eclipse.org with use of plugins
www.switchbacksoftware.com
© 2004
Emulators
Necessary for testing – device specific supplied by
vendors (like Motorola,Nokia,etc)
Not always the same as running on the device
Network Latency
File system access
Object creation during processing
Specifically, XML to Java object processing
Screen sizes
Fonts and shading
Layout
www.switchbacksoftware.com
© 2004
Ant
Ant is a Java-based build tool
Makes a repeatable build process possible
Found at http://ant.apache.org
Used for all aspects of the build process
Can easily enhance the build.xml
Helpful to separate the build into MIDlet and
Server-side for easier maintainability
www.switchbacksoftware.com
© 2004
Other Tools: Antenna
A set of Ant tasks for developing MIDP apps
Provides tasks for: compile, preverify, package,
obfuscate, running MIDlets, manipulating JAD files
and more
Tasks are named <wtk…
v0.9.12
<ANTENNA/>
http://antenna.sourceforge.net
HUGE timesaver! (unless you like inflicting
suffering on yourself)
www.switchbacksoftware.com
© 2004
Other Tools: Proguard
Obfuscator - detects and remove unused classes,
fields, methods, and attributes
Can rename remaining classes, fields, and
methods using short meaningless names
Results in smaller jars that are harder to reverseengineer
http://proguard.sourceforge.net
www.switchbacksoftware.com
© 2004
CLDC 1.1 & 3rd Party Libraries
Provides a subset of J2SE APIs available in
various libraries.
java.lang
java.io
java.util
Additional classes are provided in
javax.microedition.*
Vendor Specific APIs if you are working with a
specific SDK
kXMLRPC v1.0 for J2ME/J2EE interaction
www.switchbacksoftware.com
© 2004
Build Environment
www.switchbacksoftware.com
© 2004
Our Goals for Efficient Builds
Eliminate manual steps whenever possible
Create targets that can be chained together
Take advantage of depends=“…”
Support full compile, test, package, and deploy
functionality
Eliminate developer management of names,
settings, locations, output dirs, etc.
Provide a mechanism so that all developers have
identical base development areas
IDEs are a personal choice, while build, package and
deploy directories are not
www.switchbacksoftware.com
© 2004
Build Orientation
All paths are relative
relative paths from project dir to tools dir defined in
build.properties
Use of tools/toolname/versions
Virtually all build artifacts go into ./build.
This is so the entire ./build dir can get deleted and
recreated via a very small set of build targets.
Nothing in build is permanent.
Let’s see what it looks like…
www.switchbacksoftware.com
© 2004
Dir Structure
www.switchbacksoftware.com
© 2004
Build Environment
The build environment is critical for productive J2ME
development
Sample build.xml targets
clean – cleans all build files
core – cleans and then build the client and server
client – preverify and builds the midlet
package – packages midlet with jar and jad files
pingserver – run a test program to test the server availability
banner – print out some build information
deletedirs – Cleans any output/intermediate files from previous
builds.
mkdirs –creates new directory structure
init – initializes project scope variables
www.switchbacksoftware.com
© 2004
Why Preverify?
In the JVM we have bytecode verification, an
important step in the Java security model
Most of the bytecode verifier is not included with
the KVM because of size constraints
Preverifier makes sure the equivalent security
checks still take place
Needs to be a separate step, which is why we
have a preverified directory, and then a classes
directory (which have been preverified)
www.switchbacksoftware.com
© 2004
Building the MIDlet
The client target uses Antenna to compile and
preverify in one step
<wtkbuild
srcdir="${dir.source}"
includes="${include.midlet}"
classpath="${midlet.classpath}"
destdir="${dir.midlet.classes.nonpreverified}"
preverify="true"/>
www.switchbacksoftware.com
© 2004
Packaging
<target name="package" depends="init, banner, core">
<wtkpackage jarfile="${dir.midlet.deploy}/${midlet.name}.jar"
jadfile="${dir.config}/${midlet.name}.jad" preverify="true"
autoversion="true" libclasspath="${gps.classpath};${kxmlrpc.classpath}"
obfuscate="false">
<fileset dir="${dir.midlet.classes.nonpreverified}"/>
<fileset dir="${dir.resource}"/>
</wtkpackage>
<!-- Copy and rename our project template JAD to the deploy directory
so it is side-by-side with the Jar file. This is needed so both Jad and
Jar reside together for deployment to a phone.
-->
<copy file="${dir.config}/${midlet.name}.jad“
tofile="${dir.midlet.deploy}/${midlet.name}.jad"/>
<!-- Copy just created Jar to the config directory. This is needed to
synchronize the deploy and Motorola emulation areas. In our setup, Motorola
emulates out of the config dir. -->
<copy file="${dir.midlet.deploy}/${midlet.name}.jar"
tofile="${dir.config}/${midlet.name}.jar"/>
</target>
www.switchbacksoftware.com
© 2004
JAD File
Used by AMS to manage MIDlets
Has to be supplied to run a CLDC-compliant app
File extension of .jad
Some attributes of the manifest file are duplicated
in the JAD
MUST match information in the JAR Manifest otherwise
MIDlet won’t load
Name/Value pair, separated by a colon and
optional whitespace
For a full list of supported JAD entries reference:
http://java.sun.com/j2me/docs/wtk2.0/user_html/Ap_Attributes.html
Usually build JAD by hand first time, but update
via Antenna WtkJad build task
www.switchbacksoftware.com
© 2004
Sample JAD
MIDlet-1: MyMIDlet, MyMIDlet.png, MyMIDlet
MIDlet-2: FirstConnection, , FirstConnection
MIDlet-Jar-Size: 100
MIDlet-Jar-URL: MyMIDlet.jar
MIDlet-Name: MyMIDlet
MIDlet-Vendor: Switchback Software
MIDlet-Version: 1.0
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0
www.switchbacksoftware.com
© 2004
Manifest Files
Need both a manifest file for the JAR as well as a
JAD file.
Need to have matching information.
Why then do we need to duplicate info?
MIDP devices fetch the JAD first (much smaller)
before downloading the JAR.
Gives a user a chance to determine whether they want
the download to continue
www.switchbacksoftware.com
© 2004
MIDlet Suites
We’ve provided Homebase1, Homebase2,
and Homebase in a MIDlet suite
MIDlet suite is a JAR file that contains 1 or
more MIDlets
MIDlet-<n> contains info about that MIDlet
MIDlet-1: HomeBase, , com.sb.dwm.midlet.HomeBase
MIDlet-2: HomeBase1, , com.sb.dwm.midlet.HomeBase1
<n> MIDlets get packaged in the same JAR
file
AMS gives choice for loading each MIDlet
www.switchbacksoftware.com
© 2004
Emulators
Necessary for testing – device specific supplied by
vendors (like Motorola,Nokia,etc)
Not always the same as running on the device
Network Latency
File system access
Object creation during processing
Specifically, XML to Java object processing
Screen sizes
Fonts and shading
Layout
www.switchbacksoftware.com
© 2004
Deploying onto devices
2 ways – serial cable or OTA
Hook up a serial cable from your dev machine to
your device
Usually vendor will provide some type of development
tool
Motorola has the WebJAL which is good…when it
works.
Over the air provisioning is a standard protocol for
downloading
Can test OTA in WTK 2.1
Basically, you need to read (and carefully follow)
the docs for whatever device you are working with.
www.switchbacksoftware.com
© 2004
Deploying on Device
Usually you also need some type of developer
account with a device vendor.
iDEN for Motorola
If you deploy on a device you also need to make
sure that you have the correct kind of developer
carrier account
Nextel has a developer rate plan that has data access
Able to provision to a limited # of devices (like 5)
before your developer account is disabled.
www.switchbacksoftware.com
© 2004
MIDlet Development
www.switchbacksoftware.com
© 2004
MIDP
Mobile Information Device Profile
Targeted at medium- to low-end cell phones and twoway pagers
Spec addresses issues such as
Application life cycle
User interface
Persistence storage
Networking
If you really have trouble sleeping…you can read
through the MIDP 2.0 spec @
http://jcp.org/jsr/detail/118.jsp
www.switchbacksoftware.com
© 2004
MIDlets
MIDP application on a device that is managed by
the AMS
MIDlet suite is a JAR file that contains 1 or
more MIDlets
MIDlet-<n> contains info about that MIDlet
MIDlet-1: MyMIDlet, MyMIDlet.png , MyMIDlet
MIDlet-2: FirstConnection, , FirstConnection
<n> MIDlets get packaged in the same JAR
file
AMS gives choice for loading each MIDlet
www.switchbacksoftware.com
© 2004
MIDlet Lifecycle
MIDlet lifecycle defines the interaction with
the environment
Well-defined state machine that is managed
by the AMS
States include:
Paused
Active
Destroyed
Let’s take a look at how the states interact…
www.switchbacksoftware.com
© 2004
MIDlet Lifecycle
constructor
new()
startApp()
Paused
resumeRequest()
pauseApp()
Active
DestroyApp()
DestroyApp()
www.switchbacksoftware.com
© 2004
Destroyed
Lifecycle Methods
startApp() – Can be called multiple times, need to
prevent subsequent calls to startApp() from
starting the UI at the beginning a wizard
pauseApp() – usually used to release any
resources that we’re holding on too.
destroyApp() – any cleanup, prevents the user
from exiting the app if a submission of data is in
progress.
Screen interactions are handled by the
commandAction() which we’ll talk about shortly...
www.switchbacksoftware.com
© 2004
startApp()
Starts the applications, called from the AMS
Maybe called multiple times, so needs to account
for both initial and normal running semantics
Should try and return quickly because the
applications Displayable is not shown until after
this method exits.
Throws MIDletStateChangeException if app
can’t start now, but might be able to start at a later
time.
www.switchbacksoftware.com
© 2004
startApp()
Prevents subsequent calls to startApp() from
starting the UI at the beginning of the wizard
protected void startApp() throws
javax.microedition.midlet.
MIDletStateChangeException {
if (false == this.m_bInitialized) {
m_bInitialized = true;
startUI();
}
}
www.switchbacksoftware.com
© 2004
What’s Available?*
CLDC 1.1
MIDP 2.0
java.lang
javax.microedition.lcdui
+java.lang.ref
+javax.microedition.lcdui.game
java.io
+javax.microedition.media
java.util
+javax.microedition.media.control
javax.microedition.io
javax.microedition.MIDlet
+javax.microedition.pki
javax.microedition.rms
+ means new for this revision
www.switchbacksoftware.com
© 2004
* Layout : Wireless Java
Developing With J2ME, Knudsen Apress 2003
What We’re Using
Application Lifecycle package
javax.microedition.midlet
User Interface package
javax.microedition.lcdui
Networking package
javax.microedition.io
Core packages
java.lang, java.io, java.util
www.switchbacksoftware.com
© 2004
MIDP/CLDC
No dynamic loading of user defined classes
No object finalization
Java refresher: finalization is when an object can clean
up after itself before being reclaimed by the GC
No reflection
Means no RMI…no RMI means no JINI
No native methods
Can’t access platform specific features
Usually access is provided by vendor specific APIs
anyway…
www.switchbacksoftware.com
© 2004
javax.microedition.midlet
All applications must extend
public abstract class MIDlet extends Object
AMS uses this interface for state changes
destroyApp(boolean unconditional)
getAppProperty(String key) *
notifyDestroyed() *
notifyPaused() *
pauseApp()
resumeRequest() *
startApp()
checkPermission(String permission)
platformRequest(String URL)
*MIDlet to AMS method
www.switchbacksoftware.com
© 2004
javax.microedition.lcdui
High-level API’s for high portability (Screen)
Apps run and are useable on all devices
No direct access to device features
Color, device inputs, screen size
Implementation provides interaction (scrolling,
navigation, drawing)
Low-level API’s (Canvas)
Mostly for games
Also new GameCanvas in lcdui.games package
Key events
Drawing primitives
Compromises portability
www.switchbacksoftware.com
© 2004
javax.microedition.io
Flexible API for network connections using the
generic connection framework
Based around the Connection interface
MIDP 2.0 requires HTTP and HTTPS support
Optional connections include Socket, Server
Socket, TLS or SSL socket, Serial port
Formalized the connection strings
MIDP 2.0 security architecture protects users from
unauthorized network use
www.switchbacksoftware.com
© 2004
Networking
Connector.open(“<protocol>,<path>:<params>”);
Stream
Connector.open(“socket://192.168.0.1:90”);
Content
Connector.open(“file: test.bat”);
HTTP
Connector.open(“http://www.switchbacksoftware.com”);
We’ll be going into more details in the next module..
www.switchbacksoftware.com
© 2004
RMS – Record Management System
Provides MIDlet persistent storage
Simple record-oriented database
API’s found in: javax.microedition.rms
Supports enumeration, sorting, filtering of records
Shared within a MIDlet suite
We’ll talk more about this in the advanced topics
module
www.switchbacksoftware.com
© 2004
Optional Packages
PDA – adds more PDA specific APIs like Personal
Information Managers (PIM)
MM API – mobile media supports audio/video controls,
streaming media
WMA API – wireless messaging, SMS and MMS
(multimedia messaging systems)
Location API – tracking of wireless devices
J2ME Web Services API – web services related XML
processing
Bluetooth API – Bluetooth communications protocol
Security and Trust API – interaction with security smart
card
And a couple of others…
www.switchbacksoftware.com
© 2004
i730 Optional Packages
The i730 SDK has some interesting optional APIs
(although we aren’t going to go into all of them in
this course)
Interconnect/Phone call Initiation
Call receiving
Recent calls
Phonebook
Datebook
Micro 3D
Lighting
Vibrator
Customer Care
www.switchbacksoftware.com
© 2004
Building a UI
www.switchbacksoftware.com
© 2004
Somewhat…but it’s not as bad as it seems. Let’s see
how/why.
www.switchbacksoftware.com
© 2004
Let’s Talk UI
This is a particularly difficult area of mobile
development.
Different devices, different screen sizes,
grayscale, color, color depth, input capabilities.
Abstraction – define UI in abstract terms, rely on
MIDP implementation to create concrete
component
Discovery – finds out about device at runtime and
tailors UI. Mostly used for gaming apps.
We’re using the Abstraction approach
www.switchbacksoftware.com
© 2004
UI Basics
User-interface classes in javax.microedition.lcdui
(and lcdui.games)
Device’s display is represented by an instance of
Display.
Accessed from factory method getDisplay()
Display keeps track of what is currently visible,
which is an instance of Displayable
Displayable
Display
www.switchbacksoftware.com
© 2004
UI Basics
Current state of the screen is changed by
passing Displayable instances to Display’s
setCurrent() method.
What usually happens is…
1.
2.
3.
4.
Show a Displayable
Wait for some type of input
Determine what Displayable should be shown next
Rinse and Repeat
www.switchbacksoftware.com
© 2004
Interaction of UI with
Lifecycle
startApp()
setCurrent() called for first screen, if not called yet
AMS makes Displayable visible upon return from
startApp()
Possibly called several times
Don’t do initialization within startApp()!
www.switchbacksoftware.com
© 2004
Interaction of UI with
Lifecycle
pauseApp()
App can resume with another screen when reactivated
Done by using setCurrent() with the new screen
destroyApp()
UI components are freed along with other resources
www.switchbacksoftware.com
© 2004
Class Hierarchy
javax.microedition.lcdui
Displayable
javax.microedition.lcdui.game
Canvas
GameCanvas
Screen
Alert
List
Form
TextBox
www.switchbacksoftware.com
© 2004
Screen Design
Screen is central abstraction for MIDP’s UI
Can have many screens in an app, but only one
screen visible at a time
Implementation handles events
Encapsulates
Device specific graphic rendering
User input
Strings of all types must be
very very short. Screen size is
so tiny. Esoteric acronyms are
OK because this is a well
defined audience.
www.switchbacksoftware.com
© 2004
Couple Things to Note…
These examples are _very_ UI oriented, meaning we use
vastly more global variables than usual.
Also, there is a coupled management of the Wizard
between different parts of the MIDlet.
Control/management tends to spread out across methods.
Examples include:
submitTask()’s removal of commands from the Summary Form
In the commandAction() methods of the CommandListeners
(e.g. UI movement between Displayables),
And even in some of the lifecycle methods (destoryApp()
throwing an exception when submitTask thread is incomplete to
force the user to be notified by an alert and to wait.)
www.switchbacksoftware.com
© 2004
Demo
www.switchbacksoftware.com
© 2004
Event Management
www.switchbacksoftware.com
© 2004
User Input
User events defined by Command and handled by
CommandListeners
Can have many screens in an app, but only one
screen visible at a time
Implementation handles events
Encapsulates
Device specific graphic rendering
User input
Strings of all types must be very very short. Screen size is so tiny. Esoteric
acronyms are OK because this is a well defined audience.
www.switchbacksoftware.com
© 2004
Commands
Object used for event handling
CommandListener does actual work
Follows basic form of JavaBean event model; One
event each time a Command is invoked
Follow unicast listener pattern vs. multicast pattern
Displayable can only have one listener object
Add commands to screens by using
addCommand()
www.switchbacksoftware.com
© 2004
Create a Command
m_CommandSubmit = new Command("Submit",
Command.SCREEN, 0);
String label – text used to by UI
int type – hint to convey meaning of Command in
terms of commonly required application operations
int priority – hint used by MIDP implementation to
determine the relative importance of the command
Determines screen location
Visible as soft key or relegated to menu
Don’t bet on how the device will do the display but more
importantly, don’t care!
www.switchbacksoftware.com
© 2004
UI Methods
buildUI() is where the actions is
(remember…called from constructor)
commandAction() is used for handling
Commands by command instance
Displayable by displayable instance
Use of Alerts
Other method interaction such as handleExit() and
destroyApp() for protecting against shutting down before
submission to server is completed
www.switchbacksoftware.com
© 2004
Event Management
Two CommandListener event management
approaches we recommend:
1. Create an inner local CommandListener class for
Displayable
2. Put all command processing within the MIDlet’s
commandAction(). Have MIDlet implement
CommandListener and assign the MIDlet as the
CommandListener for the Displayable
We’ve included both within the examples for learning
purposes. Task list uses approach #1 with utility
methods shared by all CommandListeners
www.switchbacksoftware.com
© 2004
Event Management
While in the long run it’s probably a better,
more object oriented approach, to create
a CommandListener for each
Displayable.
However, if there are common commands
shared by many Displayables, then there
tends to be duplicated code among the
‘dedicated’ CommandListeners. In this
case, utility methods in the MIDlet (e.g.
handleExit() ) can be created and used
by the different CommandListeners.
www.switchbacksoftware.com
© 2004
Event Handling Code
public class MyMIDlet extends MIDlet implements
CommandListener {
private Command exitCommand;
...
public MyMIDlet() { ...
exitCommand = new Command("Exit",
Command.SCREEN, 1);
}
public void commandAction(Command c, Displayable s) {
if (c == exitCommand) {
destroyApp(false);
notifyDestroyed(); Strings of all types must be very very short. Screen size is so tiny. Esoteric
acronyms are OK because this is a well defined audience.
}
www.switchbacksoftware.com
© 2004
Networking
www.switchbacksoftware.com
© 2004
A Bit About Networking
We are dealing with a simple HTTP (or HTTPS in
MIDP 2.0) connection to defined IP address that
has a Servlet running.
CLDC defines a flexible API called the Generic
Connection Framework
javax.microedition.io package
Based on the Connection interface
Our networking concerns are handled under the
covers for us by the kXML-RPC implementation,
but it’s important to understand how the
mechanism works
www.switchbacksoftware.com
© 2004
Generic Connection Framework
Objective of GCF is to isolate the differences
between the use of one protocol and another into
a string characterizing the type of connection.
App code stays the same regardless of what type
of connection is being used.
CLDC doesn’t provide the implementation, but
rather the framework that can be used by the
profile (MIDP)
www.switchbacksoftware.com
© 2004
Connection Interface Hierarchy
Connection
StreamConnectionNotifier
DatagramConnection
InputConnection
OutputConnection
StreamConnection
ContentConnection
HttpConnection
www.switchbacksoftware.com
© 2004
javax.microedition.io
MIDP 2.0 requires HTTP and HTTPS support
Optional connections include Socket, Server Socket, TLS
or SSL socket, Serial port
Formalized the connection strings
Connector.open(“<protocol>,<path>:<params>”);
Ex.
Connector.open(“socket://192.168.0.1:90”);
Connector.open(“file:test.bat”);
Connector.open(“http://www.denverjug.org”);
MIDP 2.0 security architecture protects users from
unauthorized network use
Quick Demo…
www.switchbacksoftware.com
© 2004
HttpConnection
MIDP implements a subset of HTTP 1.1 (GET,
POST, HEAD)
Methods are related to dealing with http
Getting header fields & dates
Getting request and response information
HttpConnection con = null;
String url = "http://" + hostname + ":" + port;
con = ( HttpConnection ) Connector.open( url,
Connector.READ_WRITE )
con.setRequestMethod( HttpConnection.POST );
con.setRequestProperty( "Content-Length", Integer.toString(
messageLength ) );
con.setRequestProperty( "Content-Type", "text/xml" );
www.switchbacksoftware.com
© 2004
Working with Threads
www.switchbacksoftware.com
© 2004
Use of Threads
CLDC provides threads, but not the creation of a daemon
thread or ThreadGroup
Can create your own Collection at app level and manage Threads
yourself if you really wanted too…
Synchronized keyword
java.lang.Object wait(), notify(), notifyAll() available to
Thread class
No dumpStack() method, need to throw an exception
CLDC 1.1 allows for naming of a Thread and supports the
interrupt() method
Supports Thread priorities
Always use for I/O, GPS
www.switchbacksoftware.com
© 2004
Record Management Store
www.switchbacksoftware.com
© 2004
By using the RMS…let’s see how.
www.switchbacksoftware.com
© 2004
Persistent Storage Basics
Simple record-oriented database (RMS) stored in
Flash mem
Device-independent API
Records are arrays of bytes that live in record
stores
Record stores are shared within MIDlet suite
MIDP 2.0 allows for optional sharing of record stores
between MIDlet suites
Support for enumeration, sorting, and filtering
Atomic update for single records
www.switchbacksoftware.com
© 2004
RMS Classes and Interfaces
Defined in javax.microedition.rms package
RecordStore
Collection of records
RecordEnumerator
RecordStore enumerator
Interfaces
RecordComparator
RecordFilter
RecordListener
www.switchbacksoftware.com
© 2004
Using Records
Old
J2ME
RecordStore RecordStore
int id byte[] data
int id byte[] data
int id byte[] data
Nothing fancy here
Array of bytes
Integer values used a unique ID
Records can be written using java.io API’s in
CLDC support:
DataInputStream DataOutputStream
ByteArrayInputStream ByteArrayOutputStream
www.switchbacksoftware.com
© 2004
RecordStore Operations
Standard operations you would expect:
openRecordStore(name,create)
removeRecordStore(name)
Get list of all known record stores in a MIDlet suite
listRecordStores()
Get the size of the RS
int getSize() - # of bytes used by the RS
Int getSizeAvailable() – get amount of space available
for both record data and overhead
www.switchbacksoftware.com
© 2004
Creating a RecordStore
Centered around record stores
Small database that contains data called records
javax.microedition.rms.RecordStore
Record stores are identified by name
public static final String RS_NAME = "Tasks";
try {
m_RS = RecordStore.openRecordStore(RS_NAME,
bCreateIfNecessary);
}
catch (RecordStoreException ex) {
this.m_bRecordStoreError = true;
this.m_sRecordStoreError = ex.toString();
}
www.switchbacksoftware.com
© 2004
Closing/Deleting RecordStore
Need to make sure that you release the resource
protected void destroyApp(boolean parm1) throws
javax.microedition.midlet.
MIDletStateChangeException {
try {
m_RS.closeRecordStore();
RecordStore.deleteRecordStore(RS_NAME);
}
catch (RecordStoreException ex) {
ex.printStackTrace();
System.out.println(ex.getMessage());
}
}
www.switchbacksoftware.com
© 2004
RMSMidlet
Sample MIDlet so that you can become familiar with RMS
and take a little tour.
com.sb.samples.midlet.rms package
Our objective is to introduce RMS basics including:
1.
2.
3.
4.
RecordStore creation/closing
Record adding
Record lookup filtering via RecordFilter
RecordStore deletion (no deletions take place
though very easy to add)
5. Encapsulating RecordStore I/O operations in
static Utility Class methods for consistency and
program simplification
www.switchbacksoftware.com
© 2004
RMSMidlet Description
Very simple
Creates 5 TaskRow objects.
Only object 3 has been designated as 'already
uploaded to server'.
Shows a single form with only those TaskRows
that have not been uploaded to the server (there
are 4 of them in this case).
On the form is the Record ID of the Task
User can press 'View' button to see Task
information
www.switchbacksoftware.com
© 2004
TaskRow Class
com.sb.samples.midlet.rms.TaskRow class
that acts as:
Container object for Task values
Decouples Task data from RecordStore
representation
Static utility tool for consistent, maintainable
TaskRow-to-RecordStore I/O
www.switchbacksoftware.com
© 2004
Adding Records
TaskRow offers a number of ways to add, read,
and update a record
public static int addRecord(RecordStore rs, TaskRow
taskRow) throws Exception {
byte[] bData = TaskRow.toByteArray(taskRow);
int iRecordID = rs.addRecord(bData, 0,
bData.length);
return iRecordID;
}
public static void updateRecord(RecordStore rs,
TaskRow taskRow) throws Exception {
byte[] bData = TaskRow.toByteArray(taskRow);
rs.setRecord(taskRow.iID, bData, 0,
bData.length);
}
www.switchbacksoftware.com
© 2004
Read Record
public static TaskRow readRecord(RecordStore rs, int iRecordID) throws Exception {
byte[] bData = rs.getRecord(iRecordID);
TaskRow tr = readRecord(bData);
tr.iID = iRecordID;
return tr;
}
// Maintain a single, consistent InputStream-based read mechanism
// for use by readRecord and any other usage
public static TaskRow readRecord(DataInputStream dis) throws Exception {
TaskRow tr = new TaskRow();
// the order of these reads must match
// the reads in TaskRow.toByteArray() with respect to:
// 1) the ordering of the values
// 2) the data type of each value
tr.iRadioID = dis.readInt();
tr.bUploaded = dis.readBoolean();
tr.sTask = dis.readUTF();
tr.sLongitude = dis.readUTF();
tr.sLatitude = dis.readUTF();
tr.sStatus = dis.readUTF();
return tr;
}
www.switchbacksoftware.com
© 2004
Read Record – Byte Array
// Offer a Byte Array-based reader for parts of the program that
// do not have a reference to RecordStore
// (e.g. by RecordFilter or RecordComparator that receive only
byte arrays)
public static TaskRow readRecord(byte[] bData) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(bData);
DataInputStream dis = new DataInputStream(bais);
try {
return readRecord(dis);
} finally {
if (null != dis){
try {
dis.close();
} catch (Exception e){
}
}
}
}
www.switchbacksoftware.com
© 2004
Lookup Filtering
The RMSMidlet keeps track of records that have
not been uploaded to a server.
And then we use a Filter to determine which
records need to be uploaded.
www.switchbacksoftware.com
© 2004
Filter for Records
protected TaskRow[] getUnuploadedTaskRows() throws Exception {
// Filter for tasks not yet uploaded to server
RecordFilter rf = new RecordFilterTaskNotUploaded();
// If we cared about ordering (e.g. Data created), we'd
// create a RecordComparator for that purpose. For now, don't sort.
RecordComparator nullRecordComparator = null;
boolean bKeepUpdated = false;
RecordEnumeration re = m_RS.enumerateRecords(rf,nullRecordComparator,
bKeepUpdated);
TaskRow[] aTaskRows = new TaskRow[re.numRecords()];
int i = 0;
while (re.hasNextElement()) {
int iNextRecord = 0;
try {
iNextRecord = re.nextRecordId();
TaskRow tr = TaskRow.readRecord(m_RS, iNextRecord);
aTaskRows[i] = tr;
i++;
}
catch (Exception ex) {
throw ex;
}
}
return aTaskRows;
www.switchbacksoftware.com © 2004
}
RecordFilterTaskNotUploaded Class
public class RecordFilterTaskNotUploaded
implements RecordFilter {
// only allow TaskRows that have not been uploaded to
// be accepted
public boolean matches(byte[] bCandidate) {
try {
TaskRow tr = TaskRow.readRecord(bCandidate);
if (tr.bUploaded == false) {
return true;
}
else {
return false;
}
}
catch (Exception e) {
return false;
}
}
www.switchbacksoftware.com
© 2004
RMS Tour
That concludes our RMS tour.
Unlike most tours, our RMS tour doesn’t end at a
gift shop…
www.switchbacksoftware.com
© 2004
Enterprise J2ME
(The whirlwind tour…)
www.switchbacksoftware.com
© 2004
J2ME and J2EE
MIDP App’s become a client with Middle-tier
access
XML data provided by a Servlet at well-known
URL or through Web Services
Received as streaming data using networking
API’s
Converted to String for parsing (i.e. kXML)
Display using MIDP UI elements
www.switchbacksoftware.com
© 2004
Wireless Enterprise
Mobile Services
HTTP
Web Tier
Business Tier
Tomcat
Backend
Systems
XMLRPC
Servlet
www.switchbacksoftware.com
© 2004
kXML-RPC Usage
www.switchbacksoftware.com
© 2004
MIDP & XML
MIDP networking allows access to data formats
like WML, XML
We’re just interested in XML
Upside
Easy to work with
Most are familiar with XML
Downside
Expensive
Heavy String manipulation
Footprint for the parser
For some devices, not as big a deal because
available resources are greater
www.switchbacksoftware.com
© 2004
MIDP XML Parsers
A few parsers are available for MIDP
kXML
http://www.kxml.org
Pull parser
SAX and DOM support
Written for J2ME/CLDC/MIDP
NanoXml
http://nanoxml.sourceforge.net/kvm.html
DOM
Ported
Both support XSLT
www.switchbacksoftware.com
© 2004
kXML-RPC
kXML-RPC is a J2ME implementation of the XMLRPC protocol built on top of the kXML parser.
Extremely lightweight mechanism for exchanging
data and invoking web services in a neutral,
standardized XML format.
Hides the implementation of kXML
www.switchbacksoftware.com
© 2004
Dealing with Payloads
Not really all that much to do here when using
kXML-RPC, the payload is handled for you on the
client, and the server uses a TaskHandler to get
the parameters
Let’s look at making a call, and then a sample of
what a payload might look like if you wanted to
sniff the wire…
www.switchbacksoftware.com
© 2004
Making an XML-RPC Call
Using XML-RPC is as simple as doing the
following:
String connect =
“http://www.switchbacksoftware.com/service.do”;
String ticker = "Submitting to Server";
updateUI();
XmlRpcClient xmlrpc = new XmlRpcClient(connect);
try {
String result = (String)
xmlrpc.execute(SB.submitTaskInfo, paramsArray);
www.switchbacksoftware.com
© 2004
Payload Example
<methodCall>
<methodName>SB.submitTaskInfo</methodName>
<params>
<param>
<value>
<string>Task1</string>
</value>
</param>
<param>
<value>
<string>W 12.32560</string>
</value>
</param>
<param>
<value>
<string>N 72.09090</string>
</value>
</param>
</params>
</methodCall>
www.switchbacksoftware.com
© 2004
J2ME Web Services API (WSA) JSR-172 (CLDC 1.0 & 1.1) API's standardize remote service invocation and XML
parsing - subsets of based on JAX-RPC 1.1 and SAX2
WTK 2.1, includes the libraries you need to develop MIDlets
that take advantage of J2ME WS and also includes a JAXRPC stub generator
Good article
http://developers.sun.com/techtopics/mobility/apis/articles/wsa/
www.switchbacksoftware.com
© 2004
Couple more advanced
topics…
Timers & System Properties
www.switchbacksoftware.com
© 2004
Timer and TimerTask
Introduced in J2SE 1.3 to schedule tasks for
execution by a background thread
MIDP includes the Timer and TimerTask classes
Only J2SE classes that are not included in the
CLDC but are included in MIDP
Timer API identical to J2SE version except (there’s
always an exception…) the constructor that
specifies whether the thread is a daemon is
missing.
Remember…daemon threads aren’t supported in MIDP
TimerTask exactly the same in J2SE & MIDP
www.switchbacksoftware.com
© 2004
Timer MIDlet
Found in com.sb.samples.midlet.timer package
Objectives:
1. Introduce Timer and TimerTask
2. Extend RMS basics to include an ‘Updating Task
Records’
www.switchbacksoftware.com
© 2004
TimerMIDLet Description
Creates a TimerTask that does the following each
time it is invoked:
Scans RecordStore for TaskRows that have
'not yet been uploaded‘
Picks the first Task in the list and uploads it via
submitTask()
Updates it's status value and flags it as
'uploaded‘
Updates the respective record in the
RecordStore
Makes a sound upon upload
Rebuilds the UI to reflect a dwindling list of 'not
uploaded' Tasks
www.switchbacksoftware.com
© 2004
Developer Note
We’re not going to walk through the building of the
UI, since we’ve already seen how Commands are
added and handled in other examples
www.switchbacksoftware.com
© 2004
TimerMidlet
public class TimerMidlet extends RMSMidlet {
Command m_CommandRefresh = null;
Timer m_TimerUpload = null;
TimerTask m_TimerTaskUploadATaskRow = null;
public TimerMidlet() {
super();
// need to create a TimerTask that gets the list
of not uploaded TaskRows and
// uploads them (or just the first) and
// updates the record to bUploade = true;
//
m_TimerTaskUploadATaskRow = new TimerTask(){
www.switchbacksoftware.com
© 2004
TimerMidlet
public void run() {
try {
// Get the list of un-uploaded Tasks
TaskRow[] aTaskRows = getUnuploadedTaskRows();
if (aTaskRows.length > 0){
TaskRow tr = m_aTaskRows[0];
// Submit them to server
submitTask(tr);
try {
// and update the RMS record
TaskRow.updateRecord(m_RS, tr);
}
www.switchbacksoftware.com
© 2004
TimerMidlet
catch (Exception ex) {
Alert a = new Alert("Task", "Error updating task " +
tr.sTask + ":" + ex.getMessage(), null, AlertType.ERROR);
a.setTimeout(Alert.FOREVER);
AlertType.ERROR.playSound(m_Display);
m_Display.setCurrent(a, m_Display.getCurrent());
}
try {
buildUI();
}
catch (Exception e) {
}
m_Display.setCurrent(m_FormTasks);
}
} catch (Exception e) {
}
}
};
www.switchbacksoftware.com
© 2004
Start the Timer
m_TimerUpload = new Timer();
m_TimerUpload.schedule(this.m_TimerTaskUplo
adATaskRow, 5000, 10000);
}
www.switchbacksoftware.com
© 2004
Submitting The Task
protected void submitTask(TaskRow tr) {
Vector vParams = new Vector();
vParams.addElement(tr.sTask);
vParams.addElement(tr.sLongitude);
vParams.addElement(tr.sLatitude);
vParams.addElement(new Integer(tr.iRadioID)); // radio Id
String sResult = null;
// normally would use a constants file or properties singleton
// or MIDlet attributes
String sConnect = HomeBase1.HOME_BASE_SERVER + HomeBase1.HOME_BASE_URL_FILE;
XmlRpcClient xmlrpc = new XmlRpcClient(sConnect);
try {
sResult = (String) xmlrpc.execute(HomeBase1.HOME_BASE_SUBMIT_RPC, vParams);
// When not using real phone, sleep so tos
// simulate delay for testing destroyApp(false)
// Thread.sleep(10000);
AlertType.INFO.playSound(m_Display);
tr.bUploaded = true;
}
catch (Exception e) {
sResult = "Error Submitting:" + e.getMessage();
AlertType.ERROR.playSound(m_Display);
}
tr.sStatus = sResult;
}
www.switchbacksoftware.com
© 2004
System Properties
www.switchbacksoftware.com
© 2004
Use of System Properties
CLDC does not include the java.util.Properties
class
Limited set of properties available using
System.getProperty( String key)
microedition.platform - Name of the host platform or device
(implementation-dependent)
microedition.encoding - Default character encoding Default
value:“ISO-8859-1”
microedition.configuration - Name and version of the
supported configuration “CLDC-1.1”
microedition.profiles - Names of the supported profiles
(implementation-dependent)
www.switchbacksoftware.com
© 2004
Bootcamp Wrap-up
J2ME is an exciting development opportunity
Fairly easy to transition to if you are at Java-eese.
Need to make some adjustments in your
programming habits (Come to the J2ME Best
Practices session to find out more!)
J2ME/J2EE integration will be powerful for a new
breed of applications
If your company is interested in the full 2-day
intensive J2ME developer bootcamp or requires
contracting services for mobile projects, contact
me directly at
[email protected]
Thanks!
www.switchbacksoftware.com
© 2004