J2ME Bootcamp Sue Spielman President/Senior Consulting Engineer
Transcription
J2ME Bootcamp Sue Spielman President/Senior Consulting Engineer
J2ME Bootcamp Sue Spielman sspielman@switchbacksoftware.com 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 sspielman@switchbacksoftware.com Thanks! www.switchbacksoftware.com © 2004